中介者模式下的Android底部导航栏

Mediator Pattern: 中介者模式, 用一个中介对象来封装一系列的其他对象的交互,使各个对象不需要显示的相互调用,使其耦合松散,降低多个对象类之间的通信复杂性。

详细流程以后补充, 有点忙,
代码上传了 代码

非常好理解,从字面意思中就能明白什么是中介者模式,那么对于Android底部导航栏有很多种实现方式,为什么还需要自己去设计呢?并且是使用中介者模式,典型的简单功能复杂化,是这样吗?

答案肯定是不。

从入行程序开发开始,就或听或写各种开发模式,开发模式能提升开发效率,扩展性、易维护等等,也从侧面明白了提升代码质量的方式之一就是多在业务逻辑中使用开发模式,熟练之后代码的质量自然高很多。

一 中介者模式下的Android底部导航栏

目标: 使用中介者模式实现Android底部导航栏

对于一般的具有底部导航栏的产品都可以用 底部导航栏 + ViewPager + Fragment 实现,我的思路是将ViewPager 和自定义的底部导航栏使用中介者模式完成他们的交互,在逻辑代码中简单的实现改功能,

NavLayoutMediator(mainVp,mainNav,object :NavLayoutMediator.OnConfigureNavCallback{
            override fun onConfigureNav(nav: NavLayout.Nav, position: Int) {
            }
            //设置底部导航栏的数据
            override fun navData(): MutableList<NavLayout.Nav> {
                val list = arrayListOf<NavLayout.Nav>()
                list.add(NavLayout.Nav(R.drawable.selector_nav_picture,"图片", true))
                list.add(NavLayout.Nav(R.drawable.selector_nav_picture,"视频", true))
                list.add(NavLayout.Nav(R.drawable.selector_nav_picture,"音乐", true))
                list.add(NavLayout.Nav(R.drawable.selector_nav_picture,"我的", false))
                return list
            }
        }).attach()

只需要在主页面 调用NavLayoutMediator 传入底部导航栏和ViewPager即可, 大大减少主页面中的逻辑代码

<-- 配置颜色等操作 -->
<com.sunnyweather.android.widget.NavLayout
            android:id="@+id/mainNav"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            app:navBackground="#fff5f5f5"
            app:layout_constraintBottom_toBottomOf="parent">
        </com.sunnyweather.android.widget.NavLayout>

1.1 底部导航栏 – NavLayout

自定义ConstraintLayout View,使用RecyclerView 完成底部导航栏的部署

class NavLayout : ConstraintLayout {
    private var mList = arrayListOf<Nav>()
    private var adapter: NavLayoutAdapter = NavLayoutAdapter(mList)
    private var onNavSelectedListener: OnNavSelectedListener? = null
    private var navBackground = Color.WHITE
    private var normalColor = Color.BLACK
    private var selectColor = Color.BLUE

    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        val ta = context?.obtainStyledAttributes(attrs, R.styleable.NavLayout)
      //...
        ta?.recycle()
    }

    init {
        /**
         * 可以是使用recyclerView 回调position ,利用position 更新adapter
         */
        val view = LayoutInflater.from(context).inflate(R.layout.nav_layout, this)
        val navRV = view.findViewById<RecyclerView>(R.id.navRV)
        initRv(navRV)
        bindEvent()
    }

    private fun bindEvent() {
        adapter.setOnItemClickListener { adapter, view, position ->
           // 回调点击事件
        }
    }

    fun registerOnNavSelectedListener(onNavSelectedListener: OnNavSelectedListener) {
        this.onNavSelectedListener = onNavSelectedListener
    }

    fun unRegisterOnNavSelectedListener() {
        this.onNavSelectedListener = null
    }

    fun bindToViewPager(position: Int) {
        this.mList.size
        for (i in 0 until this.mList.size) {
            this.mList[i].isSelect = position == i
        }
        adapter.notifyDataSetChanged()
    }

    fun addData(navList: MutableList<Nav>) {
        this.mList.clear()
        this.mList.addAll(navList)
        adapter.notifyDataSetChanged()
    }

    private fun initRv(navRV: RecyclerView?) {
        checkNotNull(navRV) { "RecyclerView is null" }
        navRV.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        navRV.adapter = adapter
    }

    interface OnNavSelectedListener {
        fun onNavSelected(position: Int)
    }

    inner class NavLayoutAdapter(data: MutableList<Nav>) :
        BaseQuickAdapter<Nav, BaseViewHolder>(R.layout.nav_item, data) {
        override fun convert(holder: BaseViewHolder, item: Nav) {
            //....
        }


    }
	/*
	* 底部按钮实体
	*/
    class Nav(
        val icon: Int,
        val text: String,
        var isSelect: Boolean
    )
}

详细流程以后补充, 有点忙,
代码上传了 代码

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章