145 lines
5.4 KiB
Kotlin
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)
|
|
}
|
|
} |