Skip to content

Commit 4f8040a

Browse files
committed
refactor: transform LiquidTabsUi with RecyclerView
fix: selected tab index out of bounds
1 parent 9af1587 commit 4f8040a

File tree

1 file changed

+57
-59
lines changed

1 file changed

+57
-59
lines changed

Diff for: app/src/main/java/com/osfans/trime/ime/symbol/LiquidTabsUi.kt

+57-59
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ package com.osfans.trime.ime.symbol
77
import android.content.Context
88
import android.graphics.Color
99
import android.graphics.drawable.PaintDrawable
10-
import android.widget.HorizontalScrollView
10+
import android.view.ViewGroup
11+
import androidx.recyclerview.widget.RecyclerView
12+
import com.chad.library.adapter4.BaseQuickAdapter
1113
import com.osfans.trime.data.theme.ColorManager
1214
import com.osfans.trime.data.theme.FontManager
1315
import com.osfans.trime.data.theme.Theme
@@ -16,14 +18,14 @@ import splitties.dimensions.dp
1618
import splitties.views.dsl.core.Ui
1719
import splitties.views.dsl.core.add
1820
import splitties.views.dsl.core.frameLayout
19-
import splitties.views.dsl.core.horizontalLayout
2021
import splitties.views.dsl.core.lParams
2122
import splitties.views.dsl.core.matchParent
2223
import splitties.views.dsl.core.textView
2324
import splitties.views.dsl.core.wrapContent
25+
import splitties.views.dsl.recyclerview.recyclerView
2426
import splitties.views.gravityCenter
25-
import splitties.views.gravityCenterVertical
2627
import splitties.views.horizontalPadding
28+
import splitties.views.recyclerview.horizontalLayoutManager
2729

2830
class LiquidTabsUi(
2931
override val ctx: Context,
@@ -32,8 +34,6 @@ class LiquidTabsUi(
3234
inner class TabUi : Ui {
3335
override val ctx = this@LiquidTabsUi.ctx
3436

35-
var position: Int = -1
36-
3737
val text =
3838
textView {
3939
textSize = theme.generalStyle.candidateTextSize.toFloat()
@@ -51,9 +51,6 @@ class LiquidTabsUi(
5151
},
5252
)
5353
background = rippleDrawable(ColorManager.getColor("hilited_candidate_back_color")!!)
54-
setOnClickListener {
55-
onTabClick(this@TabUi)
56-
}
5754
}
5855

5956
fun setText(str: String) {
@@ -81,71 +78,72 @@ class LiquidTabsUi(
8178
}
8279
}
8380

84-
private var tabs: Array<TabUi> = arrayOf()
85-
private var selected = -1
81+
private var onTabClick: ((Int) -> Unit)? = null
82+
83+
private class TabUiHolder(
84+
val ui: LiquidTabsUi.TabUi,
85+
) : RecyclerView.ViewHolder(ui.root)
86+
87+
private val adapter by lazy {
88+
object : BaseQuickAdapter<TabTag, TabUiHolder>() {
89+
private var selected = -1
90+
91+
override fun onCreateViewHolder(
92+
context: Context,
93+
parent: ViewGroup,
94+
viewType: Int,
95+
) = TabUiHolder(TabUi())
96+
97+
override fun onBindViewHolder(
98+
holder: TabUiHolder,
99+
position: Int,
100+
item: TabTag?,
101+
) {
102+
holder.ui.apply {
103+
setText(item!!.text)
104+
setActive(position == selected)
105+
root.run {
106+
layoutParams = ViewGroup.LayoutParams(wrapContent, matchParent)
107+
}
108+
}
109+
}
86110

87-
private var onTabClick: (TabUi.(Int) -> Unit)? = null
111+
override fun submitList(list: List<TabTag>?) {
112+
selected = -1
113+
super.submitList(list)
114+
}
88115

89-
private val horizontal = horizontalLayout()
116+
fun activateTab(position: Int) {
117+
if (position == selected) return
118+
notifyItemChanged(selected)
119+
selected = position
120+
notifyItemChanged(position)
121+
}
122+
}.apply {
123+
setOnItemClickListener { _, _, position ->
124+
onTabClick?.invoke(position)
125+
}
126+
}
127+
}
90128

91129
override val root =
92-
HorizontalScrollView(ctx).apply {
130+
recyclerView {
131+
layoutManager = horizontalLayoutManager()
132+
adapter = this@LiquidTabsUi.adapter
93133
isVerticalScrollBarEnabled = false
94134
isHorizontalScrollBarEnabled = false
95-
add(
96-
horizontal,
97-
lParams(wrapContent, matchParent) {
98-
gravity = gravityCenterVertical
99-
},
100-
)
101-
post {
102-
scrollX = tabs[selected].root.left
103-
}
104135
}
105136

106137
fun setTabs(tags: List<TabTag>) {
107-
tabs.forEach { root.removeView(it.root) }
108-
selected = -1
109-
tabs =
110-
Array(tags.size) {
111-
val tag = tags[it]
112-
TabUi().apply {
113-
position = it
114-
setText(tag.text)
115-
setActive(false)
116-
}
117-
}
118-
tabs.forEach { tabUi ->
119-
horizontal.apply {
120-
add(
121-
tabUi.root,
122-
lParams(wrapContent, matchParent) {
123-
gravity = gravityCenter
124-
},
125-
)
126-
}
127-
}
138+
adapter.submitList(tags)
128139
}
129140

130141
fun activateTab(index: Int) {
131-
if (index == selected) return
132-
if (selected >= 0) {
133-
tabs[selected].setActive(false)
134-
}
135-
tabs[index].also { tabUi ->
136-
tabUi.setActive(true)
137-
if (tabUi.root.left !in root.scrollX..root.scrollX + root.width) {
138-
root.run { post { smoothScrollTo(tabUi.root.left, scrollY) } }
139-
}
140-
}
141-
selected = index
142-
}
143-
144-
private fun onTabClick(tabUi: TabUi) {
145-
onTabClick?.invoke(tabUi, tabUi.position)
142+
adapter.activateTab(index)
143+
root.post { root.scrollToPosition(index) }
146144
}
147145

148-
fun setOnTabClickListener(listener: (TabUi.(Int) -> Unit)? = null) {
146+
fun setOnTabClickListener(listener: ((Int) -> Unit)? = null) {
149147
onTabClick = listener
150148
}
151149
}

0 commit comments

Comments
 (0)