美文网首页
底部导航栏的组合布局

底部导航栏的组合布局

作者: 爱写代码的小王子 | 来源:发表于2020-10-18 11:06 被阅读0次

本篇文章主要记录昨天学习的组合布局实现底部导航栏的效果
显示效果:


image.png

主要知识点结构:

  • 如何添加子控件到指定的布局容器
  • 如何实现布局界面之间的交互

那么如何添加子控件到指定的布局容器呢?

/**
     * 知识点:
     *     当继承于系统自带的layout时 已经规定好了规则
     *     只关心如何添加自己的子控件进去
     *     在哪里添加子控件?
     *     创建的时候添加
     * */

如何实现布局界面之间的交互

/**
这里可以通过子控件的点击事件回调来实现
* */

下面我们开始具体实现如上效果,大致流程如下

  • 首先导入我们需要的项目资源到drawablemipmap包下
  • 然后实现单个控件的显示和点按功能
  • 最后组合多个控件实现自己想要的效果

导入项目资源就不提了,我们首先先实现单个控件的显示和点按功能
BarItem.Kotlin

class BarItem: LinearLayout {

    //正常状态的icon资源
    var normalIcon:Int = 0
    //选中状态的icon资源
    var selectIcon:Int = 0
    //显示标题
    var text:String = ""
        set(value) {
            field = value
            titleTextView?.text = value
        }
    //字体颜色
    var textColor:Int = 0
    //是否选中
    var mIsSelected:Boolean = false
        set(value) {
            field = value
            updateUI()
        }

    //更新UI
    private fun updateUI() {
        if (mIsSelected){
            iconImageView?.setBackgroundResource(selectIcon)
            titleTextView?.setTextColor(textColor)
        }else{
            iconImageView?.setBackgroundResource(normalIcon)
            titleTextView?.setTextColor(Color.BLACK)
        }
    }

    private var iconImageView:ImageView? = null
    private var titleTextView:TextView? = null

    constructor(context: Context):super(context){
        initView()
    }

    constructor(context: Context,attrs:AttributeSet?):super(context, attrs){
        initView()
        initAttr(context, attrs)
    }

    //提取自定义属性
    private fun initAttr(context: Context,attrs:AttributeSet?){
        val array = context.obtainStyledAttributes(attrs,R.styleable.BarItem)
        normalIcon = array.getResourceId(R.styleable.BarItem_normalIcon,R.mipmap.home)
        selectIcon = array.getResourceId(R.styleable.BarItem_selectIcon,R.mipmap.home_selected)
        text = array.getString(R.styleable.BarItem_text).toString()
        textColor = array.getInteger(R.styleable.BarItem_textColor, Color.RED)
        mIsSelected = array.getBoolean(R.styleable.BarItem_selected,false)
        array.recycle()
    }

    //布局子控件
    private fun initView(){
        //横向布局
        orientation = VERTICAL
        //居中对齐
        gravity = Gravity.CENTER
        iconImageView = ImageView(context).also {
            val lp = LayoutParams(dp2px(32),dp2px(32))
            addView(it,lp)
        }
        titleTextView = TextView(context).also {
            val lp = LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)
            addView(it,lp)
        }
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (!mIsSelected){
            mIsSelected = true
        }
        return true
    }


    //dp值 转 px值
    private fun dp2px(dp:Int) = (context.resources.displayMetrics.density * dp).toInt()
}

在这里,我们在布局创建的时候添加子控件,也就是initView()方法在构造方法里使用,然后声明了对应的属性,mIsSelected属性用于判断是否选中,当出现点击事件时,它的值设置为true,这里我们设置了updateUI方法,用于更改对应显示的样式,这里没有设置属性私有化的目的是便于外部设置对应的属性值,我们使用xml布局显示下效果
activity_main.xml布局

<?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"
    tools:context=".MainActivity">

    <me.jrl.demo1.BarItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:normalIcon="@mipmap/home"
        app:selectIcon="@mipmap/home_selected"
        app:text="主页"
        app:textColor="@android:color/holo_red_light"
        app:selected="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

显示效果


image.png

下面我们组合实现底部导航栏
BarItem里声明的回调方法

//回调
    var callBack:((p:Int)->Unit)? = null

在点击事件中回调我们想要的position值

override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event?.action == MotionEvent.ACTION_DOWN){
            if (!mIsSelected) {
                mIsSelected = true
                callBack?.let {
                    it(position)
                }
            }
        }
        return true
    }

相关文章

网友评论

      本文标题:底部导航栏的组合布局

      本文链接:https://www.haomeiwen.com/subject/rznfmktx.html