简单实现QQ空间同款切换Tab

首先来看看QQ空间的Tab栏,中间一个加号,四个切换tab,接下来使用自定义VIew的方式来简单的实现这个Tab切换栏

image.png

与实际不同的效果都可以通过微调+换图片的方式来调整

来看看自定义出来的效果

简单实现QQ空间同款切换Tab_第1张图片
屏幕录制2020-02-10上午12.15.25.2020-02-10 00_19_08.gif

接下来来看看如何实现

1,首先使用xml拼出来这个Tab栏的基本样式



    
    

    
    
    
    
   

这里是使用LinearLayout的权重,来放5个View,里面使用任意布局,任意控件排列组合出基本样式,下面给出一个Tab的样式。最后放完整xml代码



    

    


2,接下来创建自定义view代码,用于切换各个Tab的样式和状态

package com.qquaze.widget

import android.content.Context

import android.graphics.Color

import android.util.AttributeSet

import android.widget.ImageView

import android.widget.LinearLayout

import android.widget.TextView

import com.qquaze.R

/**

* QQ空间简单切换控件

* @author songdehuai

*/

class MainTabView : LinearLayout {

    private val tvHome by lazy { findViewById(R.id.tv_home) }

    private val tvPerson by lazy { findViewById(R.id.tv_person) }

    private val tvMsg by lazy { findViewById(R.id.tv_msg) }

    private val tvVideo by lazy { findViewById(R.id.tv_video) }

    private val ivHome by lazy { findViewById(R.id.iv_home) }

    private val ivPerson by lazy { findViewById(R.id.iv_person) }

    private val ivMsg by lazy { findViewById(R.id.iv_msg) }

    private val ivVideo by lazy { findViewById(R.id.iv_video) }

    private val llHome by lazy { findViewById(R.id.ll_home) }

    private val llAdd by lazy { findViewById(R.id.ll_add) }

    private val llPerson by lazy { findViewById(R.id.ll_person) }

    private val llMsg by lazy { findViewById(R.id.ll_msg) }

    private val llVideo by lazy { findViewById(R.id.ll_video) }

    private lateinit var mListener: ListenerBuilder

    var select = 0

        set(value) {

            switchStatus(value)

            field = value

        }

    fun setListener(listenerBuilder: ListenerBuilder.() -> Unit) {

        mListener = ListenerBuilder().also(listenerBuilder)

    }

    constructor(context: Context?) : super(context) {

        initViews()

    }

    constructor(context: Context?, attrs: AttributeSet?) : super(

        context,

        attrs

    ) {

        initViews()

    }

    constructor(

        context: Context?,

        attrs: AttributeSet?,

        defStyleAttr: Int

    ) : super(context, attrs, defStyleAttr) {

        initViews()

    }

    private fun initViews() {

        //绑定xml

        inflate(context, R.layout.view_tab, this)

        //设置初始样式

        ivHome.isSelected = true

        //为每个Tab设置点击事件

        llHome.setOnClickListener {

            select = 0

            mListener.mTabClickAction?.invoke(select)

            switchStatus(select)

        }

        llMsg.setOnClickListener {

            select = 1

            mListener.mTabClickAction?.invoke(select)

            switchStatus(select)

        }

        llAdd.setOnClickListener { mListener.mAddClickAction?.invoke() }

        llPerson.setOnClickListener {

            select = 3

            mListener.mTabClickAction?.invoke(select)

            switchStatus(select)

        }

        llVideo.setOnClickListener {

            select = 4

            mListener.mTabClickAction?.invoke(select)

            switchStatus(select)

        }

    }

    /**

     * 切换选中项的状态

     */

    private fun switchStatus(select: Int) {

        when (select) {

            0 -> {

                switchView(tvHome, ivHome)

            }

            1 -> {

                switchView(tvMsg, ivMsg)

            }

            2 -> {

                //选中项为Add的时候,不做任何切换处理

            }

            3 -> {

                switchView(tvPerson, ivPerson)

            }

            4 -> {

                switchView(tvVideo, ivVideo)

            }

        }

    }

    /**

     * 切换选择控件的状态

     * 这里做一个比较懒的方法,

     * 即先把所有View的状态改为未选中的样式,

     * 之后在把需要设置成选中状态的view改为选中状态,

     * 逻辑上不是很对,不过不影响使用,也看不出来瑕疵

     */

    private fun switchView(tv: TextView, iv: ImageView) {

        tvHome.setTextColor(Color.parseColor("#767678"))

        tvPerson.setTextColor(Color.parseColor("#767678"))

        tvMsg.setTextColor(Color.parseColor("#767678"))

        tvVideo.setTextColor(Color.parseColor("#767678"))

        ivHome.isSelected = false

        ivPerson.isSelected = false

        ivMsg.isSelected = false

        ivVideo.isSelected = false

        tv.setTextColor(Color.parseColor("#FDC90F"))

        iv.isSelected = true

    }

    /**

     * 监听

     */

    inner class ListenerBuilder {

        internal var mAddClickAction: (() -> Unit)? = null

        internal var mTabClickAction: ((Int) -> Unit)? = null

        fun onAddClick(action: () -> Unit) {

            mAddClickAction = action

        }

        fun onTabClick(action: (Int) -> Unit) {

            mTabClickAction = action

        }

    }

}

完整的xml代码






    

        

        

    

    

        

        

    

    

        

            

            

        

    

    

        

        

    

    

        

        

    


给出其中一个selector_video的代码,其余就是换个图片






    

    


3,接下来看看如何使用


tab_main.setListener {

    onAddClick {

        toast("添加")

    }

    onTabClick {

        toast("点击了:$it")

    }

}

你可能感兴趣的:(简单实现QQ空间同款切换Tab)