最终效果图:

要求实现的功能
- 1、可自定义返回图标
- 2、可自定义返回文本,文本大小以及文本颜色
- 3、可自定义tab的文本内容、颜色、选中后的背景
实现思路
- 采用组合ViewGroup 的方式,分别放置AppCompatImageView、AppCompatTextView、和LinearLayoutCompat,其中LinearLayoutCompat用于添加tab标签。
- 定义三个属性类,维护图标、文本以及tab的属性样式。
- 定义接口,回调图标以及tab的点击事件
源码分析:
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.constraintlayout.widget.ConstraintLayout
import com.iflytek.lib_view.R
import java.util.ArrayList
class ToolBarWithTabView : ConstraintLayout {
val TAG = "ToolBarWithTab"
private lateinit var iconView: AppCompatImageView
private lateinit var titleView: AppCompatTextView
private lateinit var contentView: LinearLayoutCompat
private var bg = 0
private lateinit var icon:Icon
private lateinit var title:Title
private lateinit var tabText:TabText
val listOfTextView:MutableList<TextView>? = ArrayList<TextView>()
var viewClick: ViewClick? = null
constructor(context: Context) : super(context) {
init(null)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(attrs)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init(attrs)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
init(attrs)
}
private fun init(attrs: AttributeSet?) {
LayoutInflater.from(context).inflate(R.layout.view_toolbarwithtab, this, true)
initTypeArr(attrs)
initView()
layout()
initEvents()
}
private fun initTypeArr(attrs: AttributeSet?) {
val mtypeArray = context.obtainStyledAttributes(attrs, R.styleable.style_view_toolbarwithtab)
bg = mtypeArray.getResourceId(R.styleable.style_view_toolbarwithtab_bg, R.color.colorPrimary)
icon = Icon()
icon.iconWidth = mtypeArray.getDimensionPixelSize(R.styleable.style_view_toolbarwithtab_icon_width,icon.iconWidth)
icon.iconMarginLeft = mtypeArray.getDimensionPixelSize(R.styleable.style_view_toolbarwithtab_icon_margin_left,icon.iconMarginLeft)
icon.iconSrc = mtypeArray.getDrawable(R.styleable.style_view_toolbarwithtab_icon_src)
title = Title()
title.titleContent = mtypeArray.getString(R.styleable.style_view_toolbarwithtab_title_content).toString()
title.titleMarginLeft = mtypeArray.getDimensionPixelSize(R.styleable.style_view_toolbarwithtab_title_margin_left,title.titleMarginLeft)
title.titleColor = mtypeArray.getColor(R.styleable.style_view_toolbarwithtab_title_color,title.titleColor)
title.titleSize = mtypeArray.getDimensionPixelSize(R.styleable.style_view_toolbarwithtab_title_size, title.titleSize.toInt()).toFloat()
tabText = TabText()
tabText.tabTitle = mtypeArray.getString(R.styleable.style_view_toolbarwithtab_tab_title).toString()
tabText.tabTextColor = mtypeArray.getColor(R.styleable.style_view_toolbarwithtab_tab_text_color,tabText.tabTextColor)
tabText.tabMarignLeft = mtypeArray.getDimensionPixelSize(R.styleable.style_view_toolbarwithtab_tab_margin_left,tabText.tabMarignLeft)
tabText.tabBgSeclected = mtypeArray.getResourceId(R.styleable.style_view_toolbarwithtab_tab_bg_selected,tabText.tabBgSeclected)
tabText.tabBgNormal = mtypeArray.getResourceId(R.styleable.style_view_toolbarwithtab_tab_bg_normal,R.drawable.tab_normal_bg)
tabText.tabTextSize = mtypeArray.getDimensionPixelSize(R.styleable.style_view_toolbarwithtab_tab_textsize,R.drawable.tab_normal_bg)
tabText.tabTextHorizontalPadding = mtypeArray.getDimensionPixelSize(R.styleable.style_view_toolbarwithtab_tab_text_horizontal_padding,tabText.tabTextHorizontalPadding)
tabText.tabTextVerticalPadding = mtypeArray.getDimensionPixelSize(R.styleable.style_view_toolbarwithtab_tab_text_vertical_padding,tabText.tabTextVerticalPadding)
mtypeArray.recycle()
}
private fun initView() {
iconView = findViewById(R.id.icon_imageview)
titleView = findViewById(R.id.title_textview)
contentView = findViewById(R.id.tabcontent_linearlayut)
}
private fun layout(){
setBackgroundResource(bg)
icon.iconSrc?.let {
iconView.setImageDrawable(it)
}
val iconParams = iconView.layoutParams as LayoutParams
iconParams.width = icon.iconWidth
iconParams.height = icon.iconWidth
iconParams.leftMargin = icon.iconMarginLeft
iconView.layoutParams = iconParams
titleView.setText(title.titleContent)
titleView.setTextColor(title.titleColor)
titleView.setTextSize(title.titleSize)
val titleMagin = titleView.layoutParams as LayoutParams
titleMagin.leftMargin = title.titleMarginLeft
contentView.removeAllViews()
val listTab = tabText.tabTitle.split(",")
listOfTextView?.clear()
listTab.forEach {
listOfTextView?.add(addTextView(it))
}
listOfTextView?.get(0)?.setBackgroundResource(tabText.tabBgSeclected)
}
fun addTextView(title: String):TextView{
val textView = TextView(context)
textView.setText(title)
textView.setTextSize(tabText.tabTextSize.toFloat())
textView.setTextColor(tabText.tabTextColor)
textView.setBackgroundResource(tabText.tabBgNormal)
textView.setPadding(tabText.tabTextHorizontalPadding,tabText.tabTextVerticalPadding,tabText.tabTextHorizontalPadding,tabText.tabTextVerticalPadding)
textView.gravity = Gravity.CENTER_VERTICAL
val tabTextViewParams = LinearLayoutCompat.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)
tabTextViewParams.leftMargin = tabText.tabMarignLeft.div(2)
tabTextViewParams.rightMargin = tabText.tabMarignLeft.div(2)
contentView.addView(textView,tabTextViewParams)
return textView
}
fun initEvents(){
listOfTextView?.let {
it.forEachIndexed { index, textView ->
textView.setOnClickListener {
eachTextView(call = ::resetTextViewBg)
it.setBackgroundResource(tabText.tabBgSeclected)
viewClick?.tabClicked(index)
}
}
}
iconView.setOnClickListener {
viewClick?.back()
}
}
fun eachTextView(call:(TextView) -> Unit){
listOfTextView?.let {
it.forEach { textView ->
call(textView)
}
}
}
fun resetTextViewBg(textView: TextView){
textView.setBackgroundResource(tabText.tabBgNormal)
}
interface ViewClick{
fun back()
fun tabClicked(index:Int)
}
}
属性类
import android.graphics.Color
import android.graphics.drawable.Drawable
import androidx.annotation.ColorInt
data class Icon(
var iconWidth:Int = 40,
var iconMarginLeft:Int = 20,
var iconSrc: Drawable? = null
)
data class Title(
var titleContent:String = "",
var titleMarginLeft:Int = 0,
@ColorInt var titleColor:Int = Color.WHITE,
var titleSize:Float = 20F
)
data class TabText(
var tabTitle: String = "",
var tabMarignLeft:Int = 0,
@ColorInt var tabTextColor:Int = 0,
var tabBgSeclected:Int = 0,
var tabBgNormal:Int = 0,
var tabTextSize:Int = 0,
var tabTextHorizontalPadding:Int = 20,
var tabTextVerticalPadding:Int = 10
)
布局文件 view_toolbarwithtab.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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/title_textview"
app:layout_constraintLeft_toRightOf="@+id/icon_imageview"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center"
android:text="this is title"
android:layout_marginLeft="20dp"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/tabcontent_linearlayut"
android:orientation="horizontal"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center">
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
中间用到的tab背景 tab_normal_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#00FFFFFF" />
<corners android:radius="10dp" />
</shape>
使用:
<com.iflytek.lib_view.view.ToolBarWithTab
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:bg="@color/teal_700"
app:icon_width="15dp"
app:icon_margin_left="10dp"
app:icon_src="@drawable/back_btn"
app:title_content="返回"
app:title_margin_left="20dp"
app:title_color="@color/white"
app:title_size="9sp"
app:tab_title="Java,Kotlin"
app:tab_margin_left="4dp"
app:tab_text_color="@color/colorAccent"
app:tab_bg_selected="@drawable/tab_selected_bg"
app:tab_text_horizontal_padding="22dp"
app:tab_text_vertical_padding="6dp"
app:tab_textsize="9sp" />