Android MD style component (BottomNavigationView, used with Lottie)

Related articles:

  • Android material design style components (MaterialButton MaterialButtonToggleGroup, Chip, ChipGroup) (a) great summary.
  • Android MD Layout (TextInputLayout AutoCompleteTextView MaterialButton SwitchMaterial MaterialRadio)

Let’s take a look at today’s results!

Little red dot Little red dot position and style lottie

The basic use

 <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        style="@style/Widget.MaterialComponents.BottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/cccccc"
        android:theme="@style/bottomButtonNavigationStyle"
        app:itemRippleColor="@color/red"
        app:layout_constraintBottom_toBottomOf="parent"
        app:menu="@menu/button_navigation_menu" />
Copy the code

@style/bottomButtonNavigationStyle:

    <style name="bottomButtonNavigationStyle" parent="Theme.MaterialComponents.Light">
        <! Select color -->
        <item name="colorPrimary">@color/purple_500</item>

        <! -- Unselected color -->
        <item name="android:textColorSecondary">@color/cccccc</item>
    </style>
Copy the code

@menu/button_navigation_menu:


      
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <! -- Tips: BottomNavigationView set up to 5 tabs -->
    <item
        android:id="@+id/itemPage1"
        android:icon="@drawable/ic_home_24"
        android:title="page1" />

    <item
        android:id="@+id/itemPage2"
        android:icon="@drawable/ic_phone_android_24"
        android:title="page2" />

    <item
        android:id="@+id/itemPage3"
        android:icon="@drawable/ic_psychology_24"
        android:title="page3" />
</menu>
Copy the code

Parameter Description:

parameter instructions
android:theme Used to set the color of the selected button
app:itemRippleColor [app:itemRippleColor=”@null” remove water ripples!]
app:itemIconTint The icon is tonal
app:menu Settings TAB
app:itemIconSize Size of the button
app:labelVisibilityMode Button mode

App :labelVisibilityMode Comparison of 4 modes:

model instructions rendering
auto When the number of items is less than or equal to 3, the title is displayed. If the number of titles is greater than or equal to four, the title is displayed only when this parameter is selected
selected The title is displayed only when selected
labeled Always show
unlabeled Show only the icon

Style parameters:

Style parameters instructions
Widget.MaterialComponents.BottomNavigationView The default
Widget.MaterialComponents.BottomNavigationView.Colored Color (looks ugly..)
Widget.MaterialComponents.BottomNavigationView.PrimarySurface Support for dark themes

The official documentation

Tips: Set a maximum of five tabs in BottomNavigationView, otherwise you will be prompted

"Maximum number of items supported by "
              + viewClassName
              + " is "
              + maxItemCount
              + ". Limit can be checked with "
              + viewClassName
              + "#getMaxItemCount()
Copy the code

Source code analysis, two directly figure out:FIG. 1: Figure 2:

Sets the little red dot and its position

Setting the little red dot is done with BottomNavigationView#BadgeDrawable

private val badgeGravityValues = intArrayOf(
        BadgeDrawable.TOP_END, / / right
        BadgeDrawable.TOP_START, / / left
        BadgeDrawable.BOTTOM_END, / / right
        BadgeDrawable.BOTTOM_START / / lower left
    )

// Set the little red dot
 binding.bottomNavigationView.apply {
     val itemId = menu.getItem(index).itemId

     getOrCreateBadge(itemId).apply {
         isVisible = true
         number += 1
         
        // Set the location
         badgeGravity = badgeGravityValues[indexOfChild]
     }
 }
Copy the code

Auxiliary graph:Take a look at the results:

The small hole:

When you long press the event, a prompt box pops up, such as this




You can catch it by intercepting the long press event

binding.bottomNavigationView.menu.forEach {
        binding.bottomNavigationView.findViewById<View>(it.itemId)
             .setOnLongClickListener { true}}Copy the code

BottomNavigationView achieves the linkage effect with Lottie

Lottie official usage documentation

Implementation of com. Reality. Android: Lottie: 3.6.0."Copy the code

Lottie type:

  • LottieAnimationView extends the ImageView and is the default and easiest way to load Lottie animations.
  • LottieDrawable has most of the same API as LottieAnimationView, but you can use it on any view you want.
  • LottieComposition is a stateless model representation of an animation. This file can be safely cached as long as you need it, and can be reused freely between drawings/views.
  • LottieCompositionFactory allows you to create a LottieComposition from multiple inputs. This is setAnimation (…). The API uses content used by LottieDrawable and LottieAnimationView behind the scenes. Factory methods also share the same cache with these classes.

The main combination here is Lottie Edrawable

To see the full code idea:


class NavigationBottomViewModel : ViewModel() {
    // Add a maximum of 5!! (Source code)
    private val pairAnimationList = listOf(
        "tissue.json" to "Home page"."chemical.json" to "Address book"."cow.json" to "Moments of friends"."astronaout.json" to "I".)private var mCurrentPosition = 0

    fun initBottomNavigationView(bottomNav: BottomNavigationView) {
        bottomNav.menu.apply {
            for (i in pairAnimationList.indices) {
                / / add the title
                add(Menu.NONE, i, Menu.NONE, pairAnimationList[i].second)

                / / set Lottie
                setLottieDrawable(pairAnimationList, bottomNav, i)
            }
        }
        // Initialize tap listener
        initClickEvent(bottomNav)
    }

    private fun initClickEvent(bottomNav: BottomNavigationView) {
        // Listen for selected events
        bottomNav.setOnItemSelectedListener(getOnNavigationItemSelectedListener(bottomNav))
        bottomNav.setOnItemReselectedListener {
            getOnNavigationItemReselectedListener(
                bottomNav
            )
        }

        // The first one is selected by default
        bottomNav.selectedItemId = 0

        // Disable the pop-up blocking of the long press event
        bottomNav.menu.forEach {
            val menuItemView = bottomNav.findViewById<BottomNavigationItemView>(it.itemId)
            menuItemView.setOnLongClickListener {
                true}}}// Listen for changes
    // Listener for handling selection events on bottom navigation items.
    // Event listener to handle selection of bottom navigation items.
    private fun getOnNavigationItemSelectedListener(lottieBottomNavView: BottomNavigationView) =
        NavigationBarView.OnItemSelectedListener { item ->
            handleNavigationItem(item, lottieBottomNavView)
            true
        }

    // Listener for handling reselection events on bottom navigation items
    // A listener to handle the reselect event on the bottom navigation item
    private fun getOnNavigationItemReselectedListener(lottieBottomNavView: BottomNavigationView) =
        NavigationBarView.OnItemReselectedListener { item ->
            handleNavigationItem(item, lottieBottomNavView)
        }

    TODO converts Lottie to drawable set to Menu */
    private fun Menu.setLottieDrawable(
        lottieAnimationList: List<Pair<String, String>>,
        bottomNav: BottomNavigationView,
        position: Int
    ) {
        // Change to lottieDrawable
        findItem(position).icon =
            replaceLottieDrawable(lottieAnimationList[position].first, bottomNav)
    }


    /* * TODO select listen */
    private fun handleNavigationItem(item: MenuItem, bottomNav: BottomNavigationView) {
        handlePlayLottieAnimation(item, bottomNav)
        mCurrentPosition = item.itemId
    }

    private fun handlePlayLottieAnimation(item: MenuItem, bottomNav: BottomNavigationView) {
        val currentIcon = item.icon as? LottieDrawable currentIcon? .apply {// Start animation
            playAnimation()

            // Infinite playback
// loop(true)
        }

        // Handle TAB switching, icon corresponding adjustment
        if(item.itemId ! = mCurrentPosition) { bottomNav.menu.findItem(mCurrentPosition).icon = replaceLottieDrawable( pairAnimationList[mCurrentPosition].first, bottomNav ) } }/** * replace with LottieDrawable */
    private fun replaceLottieDrawable(
        jsonKey: String,
        bottomNavigationView: BottomNavigationView
    ): LottieDrawable {
        return LottieDrawable().apply {
            val result = LottieCompositionFactory.fromAssetSync(
                // Load Lottie data
                bottomNavigationView.context.applicationContext, jsonKey
            )
            callback = bottomNavigationView

            // Set the animation
            composition = result.value
        }
    }
}
Copy the code

Use:

private val viewModel: NavigationBottomViewModel by viewModels()

// Initialize Lottie with bottomNavView
viewModel.initBottomNavigationView(binding.lottieBottomNavView)
Copy the code

Other Lottie pictures are expensive to buy, so I chose a few free pictures to use.

Thought reference from

Official effect

Let’s take a look at the official effect:




This effect I see the material design source code, because it involves a lot of code, here to complete the analysis of ideas, specific details please download the complete code to view

Take a look at the layout:Details:

It looks like a custom SVG diagram to achieve this effect. To be honest, I can’t figure it out for me. But it feels like this code is automatically generated.😂

The next set (CoordinatorLayout and custom Anchor):




The complete code

Related articles:

  • Android material design style components (MaterialButton MaterialButtonToggleGroup, Chip, ChipGroup) (a) great summary.
  • Android MD Layout (TextInputLayout AutoCompleteTextView MaterialButton SwitchMaterial MaterialRadio)

That’s all for this year’s article, thank you for your attention and thumbs up, thank you!

Original is not easy, your praise is the biggest support for me!