最近要实现一个类似于下面的页面
想着每次都要自己重新写,太麻烦了,这里记录一下自己写的自定义的view。一开始本来准备用ConstraintLayout的,但是这货addview的时候总有bug,就用RelativeLayout了。
package com.android.demo.view
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.core.view.doOnLayout
import com.android.demo.R
import com.bigkoo.convenientbanner.utils.ScreenUtil
/**
* Created by JayChou on 2020/10/30.
*/
class TagView : RelativeLayout {
constructor(context: Context) : super(context) {
initView(context)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initView(context)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
initView(context)
}
private lateinit var defaultTextView: TextView //添加一个空白的view,用来精准测量每个tag的实际大小
private val tags: MutableList = mutableListOf()
private val views: MutableList = mutableListOf()
private var lastViewId = -1
private var index = 0
var click: ((String) -> Unit)? = null
private fun initView(context: Context) {
val layoutParams =
LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
defaultTextView = getTextView("")
defaultTextView.visibility = View.INVISIBLE
addView(defaultTextView, layoutParams)
}
//这里是用来提供tag的样式,替换你自己的样式
private fun getTextView(tag: String): TextView {
val textView = TextView(context)
textView.id = View.generateViewId()
textView.text = tag
// textView.setBackgroundResource(R.drawable.shape_f4f4f4_6)
// textView.setTextColor(context.resources.getColor(R.color.greyishBrownThree))
textView.setBackgroundResource(R.drawable.shape_bright_red_6)
textView.setTextColor(context.resources.getColor(R.color.white))
textView.textSize = 14f
textView.setPadding(
ScreenUtil.dip2px(context, 10f),
ScreenUtil.dip2px(context, 5f),
ScreenUtil.dip2px(context, 10f),
ScreenUtil.dip2px(context, 5f)
)
return textView
}
//添加标签
fun setTags(list: MutableList) {
clearAllViews()
this.tags.addAll(list)
addTextView()
}
fun addTags(list: MutableList) {
if (list.isNotEmpty()) {
index = this.tags.size
this.tags.addAll(list)
addTextView()
}
}
private fun addTextView() {
if (index < 0 || index >= tags.size) {
return
}
post {
val tag = tags[index]
defaultTextView.text = tag
defaultTextView.doOnLayout {
// L.i(" defaultTextView.measuredWidth $tag ${defaultTextView.measuredWidth}")
val textView = getTextView(tag)
val layoutParams =
LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
if (lastViewId == -1) {
layoutParams.addRule(ALIGN_PARENT_TOP)
layoutParams.addRule(ALIGN_PARENT_START)
} else {
val location: IntArray = intArrayOf(0, 0)
views[index - 1].getLocationOnScreen(location)
// L.i(" lastViewId $lastViewId ${measuredWidth - location[0] - views[index - 1].measuredWidth} ")
if (measuredWidth - location[0] - views[index - 1].measuredWidth > defaultTextView.measuredWidth) {
layoutParams.marginStart = ScreenUtil.dip2px(context, 10f)
layoutParams.addRule(END_OF, lastViewId)
layoutParams.addRule(ALIGN_TOP, lastViewId)
layoutParams.addRule(ALIGN_BOTTOM, lastViewId)
} else {
layoutParams.topMargin = ScreenUtil.dip2px(context, 10f)
layoutParams.addRule(ALIGN_PARENT_START)
layoutParams.addRule(BELOW, lastViewId)
}
}
lastViewId = textView.id
// L.i(" tag ${textView.id} ")
views.add(textView)
addView(textView, layoutParams)
textView.requestLayout()
requestLayout()
textView.setOnClickListener {
click?.invoke(tag)
}
textView.doOnLayout {
index += 1
addTextView()
}
}
}
}
//清除所有的tag
fun clearAllViews() {
views.forEach {
removeView(it)
}
views.clear()
tags.clear()
lastViewId = -1
index = 0
}
}
然后使用的时候,直接setTags就行了