-
Notifications
You must be signed in to change notification settings - Fork 2
/
TabItem.kt
152 lines (130 loc) · 5.34 KB
/
TabItem.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
class TabItem(context: Context, attrs: AttributeSet?, defStyleInt: Int) : View(context, attrs, defStyleInt) {
private var tabIcon: Drawable? = null
private var tabTitle: String = ""
private var tabTitleSize: Float = 24f
private var tabTitleColor: ColorStateList? = ContextCompat.getColorStateList(context, R.color.selector_tab_bar_color)
private var iconPadding: Int = 8
private var textPaint: Paint = Paint()
var showBadge: Boolean = false
private var badgeSize: Int = if (isInEditMode) 8 else 6.dp.toInt()
private var defaultTextColor = ContextCompat.getColor(context, R.color.font_9_color)
private var intrinsicWidth: Int = 0
private var intrinsicHeight: Int = 0
private var titleL: Float = 0f
private var titleT: Float = 0f
private var iconL: Int = 0
private var iconR: Int = 0
private var iconT: Int = 0
private var iconB: Int = 0
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context) : this(context, null, 0)
init {
isClickable = true
isFocusable = true
val bgdTa = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, bgdTa, true)
setBackgroundResource(bgdTa.resourceId)
val dp4 = 8.takeIf { isInEditMode } ?: 4.dp.toInt()
val sp12 = 24.takeIf { isInEditMode } ?: 12.sp.toInt()
if (attrs != null) {
val ta = context.obtainStyledAttributes(attrs, R.styleable.TabItem)
tabTitle = ta.getString(R.styleable.TabItem_tab_title) ?: "Tab"
tabTitleSize = ta.getDimensionPixelSize(R.styleable.TabItem_tab_title_size, sp12).toFloat()
tabTitleColor = ta.getColorStateList(R.styleable.TabItem_tab_title_color)
iconPadding = ta.getDimensionPixelSize(R.styleable.TabItem_tab_icon_padding, dp4)
tabIcon = ta.getDrawable(R.styleable.TabItem_tab_icon)
badgeSize = ta.getDimensionPixelSize(R.styleable.TabItem_tab_badge_size, dp4 * 2)
setTabIcon(tabIcon, ta.getDimensionPixelSize(R.styleable.TabItem_tab_icon_size, -1))
ta.recycle()
}
textPaint.isAntiAlias = true
textPaint.style = Paint.Style.FILL
}
override fun onDraw(canvas: Canvas?) {
textPaint.textSize = tabTitleSize
val titleWidth = textPaint.measureText(tabTitle)
val titleHeight = textPaint.fontMetrics.bottom - textPaint.fontMetrics.top
canvas?.let {
titleL = (measuredWidth - titleWidth) / 2f
titleT = (measuredHeight - titleHeight + (0.takeIf { intrinsicHeight == 0 } ?: (intrinsicHeight + iconPadding))) / 2f
tabIcon?.let { icon ->
iconL = (measuredWidth - intrinsicWidth) / 2
iconR = iconL + intrinsicWidth
iconT = (measuredHeight - titleHeight.toInt() - (0.takeIf { intrinsicHeight == 0 } ?: (iconPadding + intrinsicHeight))) / 2
iconB = iconT + intrinsicHeight
drawDrawable(icon, it)
if (showBadge) drawBadge(it)
}
drawTitle(it, titleHeight.toInt())
}
}
private fun drawBadge(canvas: Canvas) {
textPaint.color = ContextCompat.getColor(context, R.color.colorAccent)
canvas.drawCircle(iconR - badgeSize / 2f, iconT + badgeSize / 2f, badgeSize / 2f, textPaint)
}
private fun drawDrawable(icon: Drawable, it: Canvas) {
icon.setBounds(iconL, iconT, iconR, iconB)
icon.draw(it)
}
private fun drawTitle(it: Canvas, height: Int) {
textPaint.color = tabTitleColor?.getColorForState(drawableState, defaultTextColor) ?: defaultTextColor
it.drawText(tabTitle, titleL, titleT + height - textPaint.fontMetrics.bottom, textPaint)
it.save()
it.restore()
}
fun setTabIcon(drawable: Drawable?, sizeInPx: Int): TabItem {
tabIcon = drawable
return setTabIconSize(sizeInPx)
}
fun setTabIconSize(sizeInPx: Int): TabItem {
if (sizeInPx == -1) {
tabIcon?.let {
intrinsicWidth = it.intrinsicWidth
intrinsicHeight = it.intrinsicHeight
}
} else {
intrinsicWidth = sizeInPx
intrinsicHeight = sizeInPx
}
return this
}
fun setBadgeSize(sizeInPx: Int): TabItem {
if (sizeInPx != -1) badgeSize = sizeInPx
return this
}
fun setTitle(@StringRes resString: Int): TabItem {
tabTitle = context.getString(resString)
return this
}
fun setTitle(title: String): TabItem {
tabTitle = title
return this
}
/**
* 设置title字体大小
*/
fun setTitleSize(sizeInPx: Float): TabItem {
if (sizeInPx != -1f) tabTitleSize = sizeInPx
return this
}
/**
* 设置title与Icon间距
*/
fun setIconPadding(paddingInDp: Int): TabItem {
if (paddingInDp != -1) iconPadding = paddingInDp.dp.toInt()
return this
}
/**
* 设置title字体颜色
*/
fun setTitleColor(color: ColorStateList?): TabItem {
if (color != null) tabTitleColor = color
return this
}
override fun drawableStateChanged() {
super.drawableStateChanged()
tabIcon?.let { icon ->
icon.setState(drawableState).takeIf { icon.isStateful }
}
}
}