Files
assistant-android/app/src/main/java/com/gh/common/view/FlexLinearLayout.kt

145 lines
5.4 KiB
Kotlin

package com.gh.common.view
import android.content.Context
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.GradientDrawable
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.feature.entity.TagStyleEntity
import kotlin.math.ceil
/**
* 标签最多显示一行,显示的个数由行宽决定
*/
class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
LinearLayout(context, attrs) {
private var mTotalCount = 0
private var mTags = ArrayList<TagStyleEntity>()
private var mItemHeight = 0
private var mPadding = 0
private var mMargin = 0
private var mTextSize = 10F
private var mLastItemWidth = 0//最后更多按钮宽度
private var mTotalWidth = 0
private var mStrokeWidth = 0
var onClickListener: OnItemClickListener? = null
init {
gravity = Gravity.CENTER_VERTICAL
val ta = context.obtainStyledAttributes(attrs, R.styleable.FlexLinearLayout)
mItemHeight = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemHeight, 20F.dip2px())
mPadding = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemPadding, 5F.dip2px())
mMargin = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemMargin, 4F.dip2px())
mTextSize = ta.getDimension(R.styleable.FlexLinearLayout_itemTextSize, 10F.sp2px().toFloat())
mLastItemWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_lastItemWidth, 18F.dip2px())
mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 0.5F.dip2px())
ta.recycle()
}
fun setTags(tags: ArrayList<TagStyleEntity>) {
mTags.clear()
mTotalCount = tags.size
mTotalWidth = measuredWidth
val paint = Paint()
paint.textSize = mTextSize
var currentWidth = mLastItemWidth.toFloat()
tags.forEach {
val strWidth = getTextWidth(paint, it.name)
if (currentWidth + strWidth + mPadding * 2 + mMargin <= mTotalWidth) {
currentWidth += strWidth + mPadding * 2 + mMargin
mTags.add(it)
}
}
if (mTags.isNotEmpty()) {
addTags()
}
}
private fun getTextWidth(paint: Paint, str: String?): Int {
var width = 0
if (str != null && str.isNotEmpty()) {
val len = str.length
val widths = FloatArray(len)
paint.getTextWidths(str, widths)
for (i in 0 until len) {
width += ceil(widths[i].toDouble()).toInt()
}
}
return width
}
private fun addTags() {
removeAllViews()
mTags.forEach {
addView(createView(it))
}
if (mTotalCount != mTags.size) {
val imageView = ImageView(context).apply {
val params = LayoutParams(mLastItemWidth, mItemHeight)
layoutParams = params
setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_game_detail_label_more))
if (DarkModeUtils.isDarkModeOn(context)) setColorFilter(R.color.text_title.toColor(context))
background = createNormalBackgroundDrawable()
scaleType = ImageView.ScaleType.CENTER
}
imageView.setOnClickListener {
onClickListener?.onMoreClickListener()
}
addView(imageView)
}
}
private fun createView(tag: TagStyleEntity): View {
return TextView(context).apply {
text = tag.name
includeFontPadding = false
textSize = DisplayUtils.px2sp(context, mTextSize).toFloat()
gravity = Gravity.CENTER
val params = LayoutParams(LayoutParams.WRAP_CONTENT, mItemHeight)
params.setMargins(0, 0, mMargin, 0)
setPadding(mPadding, 0, mPadding, 0)
layoutParams = params
setTextColor(if (tag.isTop) "#${tag.color}".hexStringToIntColor() else R.color.text_title.toColor(context))
background = if (tag.isTop) createTopBackgroundDrawable(tag) else createNormalBackgroundDrawable()
setOnClickListener {
onClickListener?.onItemClickListener(tag)
}
}
}
private fun createNormalBackgroundDrawable(): GradientDrawable {
val gradientDrawable = GradientDrawable()
val isDarkModeOn = DarkModeUtils.isDarkModeOn(context)
gradientDrawable.setColor(Color.TRANSPARENT)
gradientDrawable.setStroke(mStrokeWidth, Color.parseColor(if (isDarkModeOn) "#33FFFFFF" else "#CCCCCC"))
gradientDrawable.cornerRadius = 2F.dip2px().toFloat()
return gradientDrawable
}
private fun createTopBackgroundDrawable(tag: TagStyleEntity): GradientDrawable {
val gradientDrawable = GradientDrawable()
gradientDrawable.setColor("#${tag.background}".hexStringToIntColor())
gradientDrawable.cornerRadius = 2F.dip2px().toFloat()
return gradientDrawable
}
interface OnItemClickListener {
fun onMoreClickListener()
fun onItemClickListener(tag: TagStyleEntity)
}
}