Android-Notes|BottomNavigationView-Fall in Love-Lottie, android advanced development interview questions

}
copy code

Encapsulate a BasicData to store some basic data built into the App, mainly for Lottie files:

val mNavigationAnimationList = arrayListOf(
LottieAnimation.HOME,
LottieAnimation.SUBSCRIBE,
LottieAnimation.DISCOVERY,
LottieAnimation.ACCOUNT
)

val mNavigationAnimationNightList = arrayListOf(
LottieAnimation.HOME_NIGHT,
LottieAnimation.SUBSCRIBE_NIGHT,
LottieAnimation.DISCOVERY_NIGHT,
LottieAnimation.ACCOUNT_NIGHT
)
复制代码

Step 3: Import the corresponding dependencies and add Lottie Utils

api 'com.google.android.material:material:1.2.0'
api 'com.airbnb.android:lottie:3.4.1'Copy
code

Tool class method:

/**

  • 获取 Lottie Drawable
    */
    fun getLottieDrawable(
    animation: LottieAnimation,
    bottomNavigationView: BottomNavigationView
    ): LottieDrawable {
    return LottieDrawable().apply {
    val result = LottieCompositionFactory.fromAssetSync(
    bottomNavigationView.context.applicationContext, animation.value
    )
    callback = bottomNavigationView
    composition = result.value
    }
    }

/**

  • Get Lottie json files in different modes
    */
    fun getLottieAnimationList(context: Context): ArrayList { return if (isDarkTheme(context)) { mNavigationAnimationNightList } else { mNavigationAnimationList } } Copy code






To judge whether the dark mode is a tool class, I have extracted a tool class separately. Lottie-android also has a compatible method for dark mode:

/**

  • Verify whether the current dark mode is
    */
    fun isDarkTheme(context: Context): Boolean { val flag = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK return flag == Configuration.UI_MODE_NIGHT_YES }



Step 4: Set the layout

First add a tab font selected and non-selected font color selecor:

<?xml version="1.0" encoding="utf-8"?> Copy Code

The whole wave of layout files:

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:background="@color/colorBackground"
tools:context=".module.home.activity.HomeActivity">

<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_bottom_bar"
android:layout_width="@dimen/dp_0"
android:layout_height=“wrap_content”
android:background="@color/colorBackground"
app:itemIconSize="@dimen/dp_30"
app:itemTextColor="@color/selector_menu_state_navigation"
app:labelVisibilityMode=“labeled”
app:layout_constraintBottom_toBottomOf=“parent”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent” />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy code

Step 5: Initialize BottomNavigationView and Menu

private fun initBottomNavigationView() {
nav_bottom_bar.menu.apply {
for (i in 0 until mNavigationTitleList.size) {
add(Menu.NONE, i, Menu.NONE, mNavigationTitleList[i])
}
setLottieDrawable(getLottieAnimationList(mSelfActivity))
}
initEvent()
}

private fun initEvent() { nav_bottom_bar.setOnNavigationItemSelectedListener(this) nav_bottom_bar.setOnNavigationItemReselectedListener(this) // The first one is selected by default nav_bottom_bar.selectedItemId = 0 // Handle long press MenuItem to prompt TooltipText nav_bottom_ bar.menu.forEach { val menuItemView = mSelfActivity.findViewById (it.itemId) as BottomNavigationItemView menuItemView.setOnLongClickListener { true } } }











private fun Menu.setLottieDrawable(lottieAnimationList: ArrayList) {
for (i in 0 until mNavigationTitleList.size) {
findItem(i)?.icon =
getLottieDrawable(lottieAnimationList[i], nav_bottom_bar)
}
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {
handleNavigationItem(item)
return true
}

override fun onNavigationItemReselected(item: MenuItem) {
handleNavigationItem(item)
}

private fun handleNavigationItem(item: MenuItem) {
handlePlayLottieAnimation(item)
mPreClickPosition = item.itemId
}

private fun handlePlayLottieAnimation(item: MenuItem) { val currentIcon = item.icon as? LottieDrawable currentIcon?.apply { playAnimation() } // Handle tab switching, adjust icon accordingly if (item.itemId != mPreClickPosition) { nav_bottom_bar.menu. findItem(mPreClickPosition).icon = getLottieDrawable( getLottieAnimationList(mSelfActivity)[mPreClickPosition], nav_bottom_bar ) } } Copy code













Problem Summary

Chicken Boss said:

  • Encountering problems is a good thing. Summarize more, accumulate more, and master a step-by-step process.

1. The Lottie corresponding to BottomNavigationView switching does not change, how to play?

The problem with this is that I've been caught in an inherent thinking loop from the very beginning.

Here's where I got stuck:

  • I think that because the animation is started through playAnimation to transition to the final color, then the corresponding endAnimation should be able to return to the initial state directly. Then I directly cache the previous click on the MenuItem and then modify the state.
  • tint shader modification?

After tossing and tossing for a long time, Mr. Han said, let's give up if it doesn't work.

Think about the chicken boss, how can you give up so easily?

It suddenly occurred to me yesterday, why don't I reset the Drawable again? Anyway, the initial Drawable is gray, and of course it is unselected. Then I quickly tested it in actual combat, and attached the key code:

override fun onNavigationItemReselected(item: MenuItem) {
handleNavigationItem(item)
}

private fun handleNavigationItem(item: MenuItem) {
handlePlayLottieAnimation(item)
mPreClickPosition = item.itemId
}

private fun handlePlayLottieAnimation(item: MenuItem) { val currentIcon = item.icon as? LottieDrawable currentIcon?.apply { playAnimation() } // Here it is judged that if the index of the current click is different from that of the last click, the index of the last click will be used MenuItem Icon replace if (item.itemId != mPreClickPosition) { // Get the previous MenuItem and modify the corresponding icon drawable nav_bottom_bar.menu.findItem(mPreClickPosition).icon = getLottieDrawable( getLottieAnimationList(mSelfActivity)[mPreClickPosition], nav_ bottom_bar ) } } copy code














For the specific code, refer to the actual combat part of the article.

Small lessons (experience):

  • It is really sometimes necessary to change the way of thinking. The first thing is to realize, and then to optimize. There is no basic prototype, so how can we talk about optimization?

  • As an ape, in the face of problems encountered in actual development, we must adopt multiple solutions, first to ensure the output of content and results, and secondly to reasonable and gradual optimization.

2. How to get rid of BottomNavigationView Item long press prompt?

First look at a rendering:

What is more embarrassing is that it has been used for a long time, and it was the first time I found this thing by pressing and long pressing it when I was free. With full confidence, I went to the source code about the Toast I thought in my ideal, but I couldn't find it.

Come on, let's just look through the source code together to see if we can think about and solve this problem from the perspective of source code.

Conduct a wave of brief analysis:

From the above picture and the actual coding process, we can know that the so-called bottom item is actually just a Menu whose number cannot exceed 5, and the actual trigger of this prompt must be ItemView, so let’s take a look at what it does for itemView operate?

When initializing ItemView, there is such a setting at the end, let’s take a look together:

@Override
public void initialize(@NonNull MenuItemImpl itemData, int menuType) {
// …
CharSequence tooltipText = !TextUtils.isEmpty(itemData.getTooltipText())
? itemData.getTooltipText()
: itemData.getTitle();
TooltipCompat.setTooltipText(this, tooltipText);
setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
}
复制代码

tooltipText, tooltip text? A little dazed, it seems interesting. There is a verification here. If the tooltipText is empty, use the title value. Anyway, use its own value. Finally, set the final judgment result to setTooltipText. Let's take a look at what is done in this set?

/**

  • Helper class used to emulate the behavior of {@link View#setTooltipText(CharSequence)} prior
  • to API level 26.

/
public class TooltipCompat {
/
*

  • Sets the tooltip text for the view.
  • Prior to API 26 this method sets or clears (when tooltip is null) the view's

  • OnLongClickListener and OnHoverListener. A toast-like subpanel will be created on long click
  • or mouse hover.
  • @param view the view to set the tooltip text on
  • @param tooltipText the tooltip text
    */
    public static void setTooltipText(@NonNull View view, @Nullable CharSequence tooltipText) {
    if (Build.VERSION.SDK_INT >= 26) {
    view.setTooltipText(tooltipText);
    } else {
    TooltipCompatHandler.setTooltipText(view, tooltipText);
    }
    }

private TooltipCompat() {}
}
Copy code

The comment is quite clear. A tooltip text added in Api 26 is mainly used for a long press or mouse hover prompt, similar to Toast.

Continue to look down, what exactly does set do?

/**

  • Sets the tooltip text which will be displayed in a small popup next to the view.
  • // …
  • // The key point is the description of the following parameters, if you do not need to set null
  • @param tooltipText the tooltip text, or null if no tooltip is required
  • @see #getTooltipText()
  • @attr ref android.R.styleable#View_tooltipText
    */
    public void setTooltipText(@Nullable CharSequence tooltipText) { if (TextUtils.isEmpty(tooltipText)) { setFlags(0, TOOLTIP); // hide hidden? Long live the chicken boss hideTooltip (); mTooltipInfo = null; } else { // ... } }









It can be clearly seen that if you don't want to display this so-called tooltipText, you only need to set it to empty. I probably have an idea here, but I am still curious about what this thing pops up? Continue to look down.

@UnsupportedAppUsage
void hideTooltip() {
// …
if (mTooltipInfo.mTooltipPopup == null) {
return;
}
mTooltipInfo.mTooltipPopup.hide();
mTooltipInfo.mTooltipPopup = null;
// …
}
复制代码

Ummm, it turned out to be a PopupWindow.

Well, back to the topic, cancel the tooltipText prompt when BottomNavigationView is long pressed.

Loop through the Menu and set tooltipText to null.

nav_bottom_bar.menu.forEach { TooltipCompat.setTooltipText(mSelfActivity.findViewById(it.itemId ) ,null) }


Take a look at the renderings:

ummm. Not right. For the first time, the two Tab long presses are as expected. What about the follow-up?

Ummm, or, I just cut off my thoughts? Directly intercept a wave of long press events?

nav_bottom_bar.menu.forEach {
val menuItemView = mSelfActivity.findViewById(it.itemId) as BottomNavigationItemView
menuItemView.setOnLongClickListener {
true
}
}

Run a wave to see?

Ummm, it hurts so much.

3. When selected, I want to have an animation, how can I do it? (2020/09/03)

In the middle of the night yesterday, Mr. Han sent a message, part of which is as follows:

Ummm, I'm so heartbroken. All ready to fall asleep.

Well, simply analyze the waves.

First attach the item part code about BottomNavigationView, which is actually Menu Item:

All walks of life will eliminate some poor ability, not just the IT industry, so don't be intimidated by topics like programmers eating youth food, etc., and don't think that if you find a job, you can enjoy a comfortable life , While you are at ease, others are struggling to move forward, so that the gap with others will become more and more distant. Come on, I hope that each of us can become a better self.

The folder has the following study notes, download them yourself!

  • BAT big factory interview questions, exclusive interview kit,

  • Free collection of materials, including data structure, Kotlin, computer network, Framework source code, data structure and algorithm, applet, NDK, Flutter,


    Run forward, so that the gap with others will become more and more distant, come on, hope, each of us can become a better version of ourselves.

  • Click here to communicate and learn with us

The folder has the following study notes, download them yourself!

  • BAT big factory interview questions, exclusive interview kit,

  • Free collection of materials, including data structure, Kotlin, computer network, Framework source code, data structure and algorithm, applet, NDK, Flutter,

    [External link image transfer...(img-R7UMVnWk-1645164336797)]

Guess you like

Origin blog.csdn.net/m0_66264630/article/details/123002146