android MD风格组件(BottomNavigationView,配合lottie使用)

Posted android超级兵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android MD风格组件(BottomNavigationView,配合lottie使用)相关的知识,希望对你有一定的参考价值。

android MD风格组件(BottomNavigationView,配合lottie使用[三]

相关文章:

先来看今天完成的效果!

小红点小红点位置以及样式lottie

基本使用

 <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" />

@style/bottomButtonNavigationStyle:

    <style name="bottomButtonNavigationStyle" parent="Theme.MaterialComponents.Light">
        <!--        是选中颜色-->
        <item name="colorPrimary">@color/purple_500</item>

        <!--        未选中颜色 -->
        <item name="android:textColorSecondary">@color/cccccc</item>
    </style>

@menu/button_navigation_menu:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <!--    tips: BottomNavigationView 最多设置5个tab-->
    <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>

参数介绍:

参数说明
android:theme常用来设置选中按钮颜色
app:itemRippleColor水波纹颜色 [app:itemRippleColor="@null" 去除水波纹!]
app:itemIconTinticon色调
app:menu设置tab
app:itemIconSize按钮大小
app:labelVisibilityMode按钮模式

app:labelVisibilityMode模式4种模式对比:

模式说明效果图
autoitem 少于等于 3 个时,标题处于显示状态;大于等于 4 个,选中才显示标题
selected选中才显示标题
labeled一直显示
unlabeled只显示icon

style参数:

style参数说明
Widget.MaterialComponents.BottomNavigationView默认
Widget.MaterialComponents.BottomNavigationView.Colored彩色(看着很丑…)
Widget.MaterialComponents.BottomNavigationView.PrimarySurface支持深色主题

官方文档

tips: BottomNavigationView 最多设置5个tab,否则会提示

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

源码分析,两张图直接搞明白:
图一:

图二:

设置小红点及其位置

设置小红点需要通过BottomNavigationView#BadgeDrawable来设置

private val badgeGravityValues = intArrayOf(
        BadgeDrawable.TOP_END, // 右上
        BadgeDrawable.TOP_START, // 左上
        BadgeDrawable.BOTTOM_END, // 右下
        BadgeDrawable.BOTTOM_START // 左下
    )

// 设置小红点
 binding.bottomNavigationView.apply 
     val itemId = menu.getItem(index).itemId

     getOrCreateBadge(itemId).apply 
         isVisible = true
         number += 1
         
        // 设置位置
         badgeGravity = badgeGravityValues[indexOfChild]
     
 

辅助图:

来看看效果:

小坑:

长按事件的时候,回弹出提示框,例如这样


你可以通过拦截长按事件来捕获它

binding.bottomNavigationView.menu.forEach 
        binding.bottomNavigationView.findViewById<View>(it.itemId)
             .setOnLongClickListener  true 
     

BottomNavigationView 配合lottie实现联动效果

Lottie官方使用文档

implementation com.airbnb.android:lottie:3.6.0"

lottie 类型:

  • LottieAnimationView 扩展 ImageView 并且是加载 Lottie 动画的默认和最简单的方法。
  • LottieDrawableLottieAnimationView 有大部分相同的 API,但你可以在任何你想要的视图上使用它。
  • LottieComposition是动画的无状态模型表示。只要您需要,此文件就可以安全地缓存,并且可以在绘图/视图之间自由重用。
  • LottieCompositionFactory 允许您从多个输入创建 LottieComposition。这就是setAnimation(…)API 在后台使用LottieDrawable和LottieAnimationView使用的内容。工厂方法也与这些类共享相同的缓存。

这里结合主要用到了LottieDrawable

来看完整代码思路:


class NavigationBottomViewModel : ViewModel() 
    // 注意 最多能放5个!!(源码规定)
    private val pairAnimationList = listOf(
        "tissue.json" to "首页",
        "chemical.json" to "通讯录",
        "cow.json" to "朋友圈",
        "astronaout.json" to "我的",
    )

    private var mCurrentPosition = 0

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

                // 设置lottie
                setLottieDrawable(pairAnimationList, bottomNav, i)
            
        
        // 初始化点击监听
        initClickEvent(bottomNav)
    

    private fun initClickEvent(bottomNav: BottomNavigationView) 
        // 监听选中事件
        bottomNav.setOnItemSelectedListener(getOnNavigationItemSelectedListener(bottomNav))
        bottomNav.setOnItemReselectedListener 
            getOnNavigationItemReselectedListener(
                bottomNav
            )
        

        // 默认选中第一个
        bottomNav.selectedItemId = 0

        // 禁止长按弹出 拦截长按事件
        bottomNav.menu.forEach 
            val menuItemView = bottomNav.findViewById<BottomNavigationItemView>(it.itemId)
            menuItemView.setOnLongClickListener 
                true
            
        
    

    // 监听变化
    // Listener for handling selection events on bottom navigation items.
    // 事件监听器来处理选择底部导航项。
    private fun getOnNavigationItemSelectedListener(lottieBottomNavView: BottomNavigationView) =
        NavigationBarView.OnItemSelectedListener  item ->
            handleNavigationItem(item, lottieBottomNavView)
            true
        

    // Listener for handling reselection events on bottom navigation items
    // 用于处理底部导航项上的重新选择事件的侦听器
    private fun getOnNavigationItemReselectedListener(lottieBottomNavView: BottomNavigationView) =
        NavigationBarView.OnItemReselectedListener  item ->
            handleNavigationItem(item, lottieBottomNavView)
        

    /*
   * 作者:android 超级兵
   * 创建时间: 1/24/22 7:46 PM
   * TODO 将lottie转变为drawable 设置给menu
   */
    private fun Menu.setLottieDrawable(
        lottieAnimationList: List<Pair<String, String>>,
        bottomNav: BottomNavigationView,
        position: Int
    ) 
        // 转变为lottieDrawable
        findItem(position).icon =
            replaceLottieDrawable(lottieAnimationList[position].first, bottomNav)
    


    /*
     * 作者:android 超级兵
     * 创建时间: 1/26/22 1:50 PM
     * TODO 选中监听
     */
    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 
            // 开启动画
            playAnimation()

            // 无限播放
//            loop(true)
        

        // 处理 tab 切换,icon 对应调整
        if (item.itemId != mCurrentPosition) 
            bottomNav.menu.findItem(mCurrentPosition).icon =
                replaceLottieDrawable(
                    pairAnimationList[mCurrentPosition].first,
                    bottomNav
                )
        
    

    /**
     * 替换成 LottieDrawable
     */
    private fun replaceLottieDrawable(
        jsonKey: String,
        bottomNavigationView: BottomNavigationView
    ): LottieDrawable 
        return LottieDrawable().apply 
            val result = LottieCompositionFactory.fromAssetSync(
                // 加载lottie 数据
                bottomNavigationView.context.applicationContext, jsonKey
            )
            callback = bottomNavigationView

            // 设置动画
            composition = result.value
        
    

使用:

private val viewModel: NavigationBottomViewModel by viewModels()

// 初始化lottie 与 bottomNavView 结合起来
viewModel.initBottomNavigationView(binding.lottieBottomNavView)

lottie图片出处,购买其他lottie图片要掏美子,有点贵,所以就选了几张免费的图来用用…

思路参考自

官方的效果

先来看看官方实现的效果:


这种效果我是看material design源码看到的,因为涉及到很多的代码,这里自分析完成思路,具体细节请下载完整代码查看

先来看一眼布局:

具体细节:

思路分析:
官方感觉像是自定义svg图,来实现这个效果的,说实话,要给我我是弄不出来… 但是感觉这种代码像是自动生成的.😂

下集预告(CoordinatorLayout与自定义anchor):


完整代码

相关文章:

今年的文章就写到这里,感谢你的关注点赞 ,谢谢!

原创不易,您的点赞就是对我最大的支持!

以上是关于android MD风格组件(BottomNavigationView,配合lottie使用)的主要内容,如果未能解决你的问题,请参考以下文章

Android 走向MD的配色风格

如何对Android MaterialCalendars各个组件进行风格化处理?

android material design 风格组件(MaterialButton,MaterialButtonToggleGroup,Chip,ChipGroup)大汇总.

架构风格

如何评价 3.9 及 4.0 版 Bilibili for Android

安卓MD风格的布局记录