Android使用Builder建造者模式打造通用导航栏

前言

实际项目开发中,每个界面对应的头部导航栏样式都大差不差,如果通过布局文件include的方式添加显示,当需求改动时,就不是很方便,那我们能不能打造一套通用的导航栏,通过代码来进行约束实现呢?

具体实现

定义导航栏接口规范

interface INavigation {
    /**
     * 绑定布局ID
     */
    fun bindLayoutId(): Int

    /**
     * 给View设置参数
     */
    fun <T : AbsNavigationBar.Builder> applyView(builder: T)

}

定义导航栏抽象类

abstract class AbsNavigationBar(private val builder: Builder) : INavigation {

    private var view: View? = null

    init {
        //创建和绑定布局
        view = LayoutInflater.from(builder.context).inflate(bindLayoutId(), builder.parent, false)
        builder.parent.addView(view, 0)
        applyView(builder)
    }

    fun getString(id: Int): String {
        return builder.context.getString(id)
    }

    fun getColor(id: Int): Int {
        return ContextCompat.getColor(builder.context, id)
    }

    fun setText(vid: Int, text: CharSequence) {
        val tv = findViewById<TextView>(vid)
        if (tv.visibility != View.VISIBLE) {
            tv.visibility = View.VISIBLE
        }
        tv.text = text
    }

    fun setImageResource(vid: Int, resId: Int) {
        val imageView = findViewById<ImageView>(vid)
        if (imageView.visibility != View.VISIBLE) {
            imageView.visibility = View.VISIBLE
        }
        imageView.setImageResource(resId)
    }


    fun setOnClickListener(vid: Int, listener: View.OnClickListener?) {
        val view = findViewById<View>(vid)
        if (view.visibility != View.VISIBLE) {
            view.visibility = View.VISIBLE
        }
        view.setOnClickListener(listener)
    }

    private fun <T : View> findViewById(id: Int): T {
        return view!!.findViewById(id)
    }

    /**
     * 构建导航栏
     */
    abstract class Builder(val context: Context, val parent: ViewGroup) {
        /**
         * 构建导航栏方法
         */
        abstract fun build(): AbsNavigationBar

    }

}

打造通用的NavigationBar

class CommonNavigationBar private constructor(builder: Builder) : AbsNavigationBar(builder) {

    /**
     * 绑定布局
     */
    override fun bindLayoutId(): Int {
        return R.layout.common_navigation_bar
    }


    /**
     * 绑定资源
     */
    override fun <T : AbsNavigationBar.Builder> applyView(builder: T) {
        val result = builder as Builder
        setText(R.id.tv_title, result.title)
        setText(R.id.tv_left, result.leftTitle)
        setText(R.id.tv_right, result.rightTitle)
        setOnClickListener(R.id.tv_right,result.rightOnClickListener)
    }

    class Builder(context: Context, parent: ViewGroup) : AbsNavigationBar.Builder(context,parent) {
        //中间标题
        var title: String = ""

        //左边图片
        var leftIcon: Int = 0

        //右边图片
        var rightIcon: Int = 0

        //左边文字
        var leftTitle: String = ""

        //右边文字
        var rightTitle: String = ""

        //整体背景颜色
        var bgColor: Int = 0

        //左侧点击事件
        var leftOnClickListener: OnClickListener? = null


        //右侧点击事件
        var rightOnClickListener: OnClickListener? = null

        fun setTitle(title: String): Builder {
            this.title = title
            return this
        }

        fun setLeftTitle(leftTitle: String): Builder {
            this.leftTitle = leftTitle
            return this
        }

        fun setRightTitle(rightTitle: String): Builder {
            this.rightTitle = rightTitle
            return this
        }

        fun setLeftIcon(leftIcon: Int): Builder {
            this.leftIcon = leftIcon
            return this
        }

        fun setRightIcon(rightIcon: Int): Builder {
            this.rightIcon = rightIcon
            return this
        }

        fun setBgColor(bgColor: Int): Builder {
            this.bgColor = bgColor
            return this
        }

        fun setLeftOnClickListener(leftOnClickListener: OnClickListener): Builder {
            this.leftOnClickListener = leftOnClickListener
            return this
        }

        fun setRightOnClickListener(rightOnClickListener: OnClickListener): Builder {
            this.rightOnClickListener = rightOnClickListener
            return this
        }

        override fun build(): CommonNavigationBar {
            return CommonNavigationBar(this)
        }

    }
}

实践使用

   CommonNavigationBar.Builder(this, findViewById(android.R.id.content))
            .setTitle("This is Title")
            .setRightTitle("Right Title")
            .setRightOnClickListener {
                Toast.makeText(this@MainActivity, "Click Right", Toast.LENGTH_LONG).show()
            }
            .build()

小结

通过使用Builder建造者模式,我们将复杂对象的建造过程和它的表示进行分离,对于本文中的导航栏构建就十分适用。

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值