美文网首页
简单实现QQ空间同款切换Tab

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

作者: songdehuai | 来源:发表于2020-02-10 00:12 被阅读0次

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

    image.png

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

    来看看自定义出来的效果

    屏幕录制2020-02-10上午12.15.25.2020-02-10 00_19_08.gif

    接下来来看看如何实现

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

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:weightSum="5"
        app:layout_constraintBottom_toBottomOf="parent">
        
        <View1
            android:layout_weight="1"
            ...
                />
    
        <View2
            android:layout_weight="1"
            ...
                />
        <View3
            android:layout_weight="1"
            ...
                />
        <View4
            android:layout_weight="1"
            ...
                />
        <View5
            android:layout_weight="1"
            ...
                />
       
    </LinearLayout>
    

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

    <LinearLayout
    
        android:id="@+id/ll_home"
    
        android:layout_width="match_parent"
    
        android:layout_height="match_parent"
    
        android:layout_weight="1"
    
        android:gravity="center"
    
        android:orientation="vertical">
    
        <ImageView
    
            android:id="@+id/iv_home"
    
            android:layout_width="24dp"
    
            android:layout_height="24dp"
    
            android:background="@drawable/selector_home" />
    
        <TextView
    
            android:id="@+id/tv_home"
    
            android:layout_width="match_parent"
    
            android:layout_height="wrap_content"
    
            android:gravity="center"
    
            android:text="首页"
    
            android:textColor="#1186DE" />
    
    </LinearLayout>
    

    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<TextView>(R.id.tv_home) }
    
        private val tvPerson by lazy { findViewById<TextView>(R.id.tv_person) }
    
        private val tvMsg by lazy { findViewById<TextView>(R.id.tv_msg) }
    
        private val tvVideo by lazy { findViewById<TextView>(R.id.tv_video) }
    
        private val ivHome by lazy { findViewById<ImageView>(R.id.iv_home) }
    
        private val ivPerson by lazy { findViewById<ImageView>(R.id.iv_person) }
    
        private val ivMsg by lazy { findViewById<ImageView>(R.id.iv_msg) }
    
        private val ivVideo by lazy { findViewById<ImageView>(R.id.iv_video) }
    
        private val llHome by lazy { findViewById<LinearLayout>(R.id.ll_home) }
    
        private val llAdd by lazy { findViewById<LinearLayout>(R.id.ll_add) }
    
        private val llPerson by lazy { findViewById<LinearLayout>(R.id.ll_person) }
    
        private val llMsg by lazy { findViewById<LinearLayout>(R.id.ll_msg) }
    
        private val llVideo by lazy { findViewById<LinearLayout>(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代码

    
    <?xml version="1.0" encoding="utf-8"?>
    
    <LinearLayout 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="50dp"
    
        android:layout_alignParentBottom="true"
    
        android:orientation="horizontal"
    
        android:weightSum="5"
    
        app:layout_constraintBottom_toBottomOf="parent">
    
        <LinearLayout
    
            android:id="@+id/ll_home"
    
            android:layout_width="match_parent"
    
            android:layout_height="match_parent"
    
            android:layout_weight="1"
    
            android:gravity="center"
    
            android:orientation="vertical">
    
            <ImageView
    
                android:id="@+id/iv_home"
    
                android:layout_width="24dp"
    
                android:layout_height="24dp"
    
                android:background="@drawable/selector_home"
    
                tools:src="@drawable/ic_home_yes" />
    
            <TextView
    
                android:id="@+id/tv_home"
    
                android:layout_width="match_parent"
    
                android:layout_height="wrap_content"
    
                android:gravity="center"
    
                android:text="首页"
    
                android:textColor="#FDC90F" />
    
        </LinearLayout>
    
        <LinearLayout
    
            android:id="@+id/ll_msg"
    
            android:layout_width="match_parent"
    
            android:layout_height="match_parent"
    
            android:layout_weight="1"
    
            android:gravity="center"
    
            android:orientation="vertical">
    
            <ImageView
    
                android:id="@+id/iv_msg"
    
                android:layout_width="24dp"
    
                android:layout_height="24dp"
    
                android:background="@drawable/selector_msg" />
    
            <TextView
    
                android:id="@+id/tv_msg"
    
                android:layout_width="match_parent"
    
                android:layout_height="wrap_content"
    
                android:gravity="center"
    
                android:text="消息"
    
                android:textColor="#767678" />
    
        </LinearLayout>
    
        <LinearLayout
    
            android:id="@+id/ll_add"
    
            android:layout_width="match_parent"
    
            android:layout_height="wrap_content"
    
            android:layout_gravity="center"
    
            android:layout_weight="1"
    
            android:gravity="center"
    
            android:orientation="vertical"
    
            app:layout_constraintLeft_toLeftOf="parent"
    
            app:layout_constraintRight_toRightOf="parent"
    
            app:layout_constraintTop_toTopOf="parent">
    
            <RelativeLayout
    
                android:layout_width="match_parent"
    
                android:layout_height="48dp"
    
                android:gravity="center">
    
                <View
    
                    android:layout_width="match_parent"
    
                    android:layout_height="match_parent"
    
                    android:layout_centerInParent="true"
    
                    android:background="#FDC90F" />
    
                <ImageView
    
                    android:layout_width="24dp"
    
                    android:layout_height="24dp"
    
                    android:layout_centerInParent="true"
    
                    android:src="@drawable/ic_add_center" />
    
            </RelativeLayout>
    
        </LinearLayout>
    
        <LinearLayout
    
            android:id="@+id/ll_person"
    
            android:layout_width="match_parent"
    
            android:layout_height="match_parent"
    
            android:layout_weight="1"
    
            android:gravity="center"
    
            android:orientation="vertical">
    
            <ImageView
    
                android:id="@+id/iv_person"
    
                android:layout_width="24dp"
    
                android:layout_height="24dp"
    
                android:background="@drawable/selector_person" />
    
            <TextView
    
                android:id="@+id/tv_person"
    
                android:layout_width="match_parent"
    
                android:layout_height="wrap_content"
    
                android:gravity="center"
    
                android:text="我的"
    
                android:textColor="#767678" />
    
        </LinearLayout>
    
        <LinearLayout
    
            android:id="@+id/ll_video"
    
            android:layout_width="match_parent"
    
            android:layout_height="match_parent"
    
            android:layout_weight="1"
    
            android:gravity="center"
    
            android:orientation="vertical">
    
            <ImageView
    
                android:id="@+id/iv_video"
    
                android:layout_width="24dp"
    
                android:layout_height="24dp"
    
                android:background="@drawable/selector_video" />
    
            <TextView
    
                android:id="@+id/tv_video"
    
                android:layout_width="match_parent"
    
                android:layout_height="wrap_content"
    
                android:gravity="center"
    
                android:text="首页"
    
                android:textColor="#767678" />
    
        </LinearLayout>
    
    </LinearLayout>
    

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

    
    <?xml version="1.0" encoding="utf-8"?>
    
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:drawable="@drawable/ic_home_yes" android:state_selected="true" />
    
        <item android:drawable="@drawable/ic_home_no" android:state_selected="false" />
    
    </selector>
    

    3,接下来看看如何使用

    
    tab_main.setListener {
    
        onAddClick {
    
            toast("添加")
    
        }
    
        onTabClick {
    
            toast("点击了:$it")
    
        }
    
    }
    

    相关文章

      网友评论

          本文标题:简单实现QQ空间同款切换Tab

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