下面效果圖是工作中遇到的一個效果圖通殃,需要自定義控件來實現(xiàn)此功能。當時確實蒙了恨诱,不知道如何去實現(xiàn)骗炉。 當你看到這個效果圖后你有思路了嗎?
, 有好的想法思路可以分享分享厕鹃, 看看我的這個做法是不是太復(fù)雜了
看到這個效果圖是不是太簡單乍丈, 但是產(chǎn)品的要求是 左邊的標題要與標題最長的一個右對齊 就這一個條件當時真把 我難住了, 目前的截圖里面只有有三個條件忆矛, 但是這里面的條目的個數(shù)是不確定的
- 接下來分析一下我的思路请垛,看看我的這個思路如何?
如果能求出標題最長的控件的寬度宗收, 然后將其它標題的寬度也設(shè)置成最長標題的寬度。并設(shè)置gravity為right采驻, 是不是就能解決上面的這個問題了匈勋??
- 如何求出最長標題的寬度的呢颓影? 這時候onMeasure方法就會登上用場了。
比如接口返回了10條數(shù)據(jù)碎浇, 那么需要求出10條數(shù)據(jù)里面標題最長的那一條標題的寬度 。
思路是: 自定義 一個控件繼承自LinearLayout, 在綁定數(shù)據(jù)的時候調(diào)用bind方法奴璃, 參數(shù)是一個List城豁, 然后遍歷List,每一個item對應(yīng)于上面的效果圖的一個字條目雳旅, 然后動態(tài)的創(chuàng)建一個子item添加進當前控件,在添加進父控件之前攒盈,先測量一下左邊title的寬度, 然后把寬度最大的值保存下來僵蛛。當所有的item都遍歷結(jié)束時,就能得到最大的標題寬度充尉。然后在遍歷一次當前控件的子item衣形, 將每一個標題的寬度強制改成求出來的最大寬度,并且gravity設(shè)置成 right就能解決上面的這個問題
- 看一下我當前項目里面的核心代碼
private fun addFundView(mDatas: List<IFundTopCategoryEntity>) {
val widthMeaspec = MeasureSpec.makeMeasureSpec(ScreenUtils.getScreenWidth(), MeasureSpec.EXACTLY)
val heightMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY)
mDatas.forEach {
val view = LayoutInflater.from(context).inflate(R.layout.fund_view_top_category_item, this, false)
val rateLineView = view.findViewById<View>(R.id.rate_line)
(rateLineView.layoutParams as? LayoutParams)?.leftMargin = gap
val drawable = LinearGradientDrawable()
val startColor = ResourceUtils.getColor(R.color.day_mode_rate_line_start_color)
val endColor = ResourceUtils.getColor(R.color.day_mode_rate_line_end_color)
drawable.setColorAndRadius(startColor, endColor, 5f)
rateLineView.background = drawable
val rateTv = view.findViewById<TextView>(R.id.rate)
(rateTv.layoutParams as? LayoutParams)?.leftMargin = gap
rateTv?.text = "${it.getFundRate()}%"
val titleTv = view.findViewById<TextView>(R.id.name)
titleTv?.text = it.getFundName()
val params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
params.topMargin = gap
view.tag = it.getFundRate()
rateLineView.hide(true)
view.measure(widthMeaspec, heightMeasureSpec)
if(maxTitleWidth < titleTv.measuredWidth)
maxTitleWidth = titleTv.measuredWidth
if(maxRateWidth < rateTv.measuredWidth)
maxRateWidth = rateTv.measuredWidth
rateLineView.show()
addView(view, params)
}
fundTitleTv?.layoutParams?.width = maxTitleWidth
if (childCount > notFundChildCount) {
(notFundChildCount until childCount)?.forEach {
getChildAt(it)?.findViewById<View>(R.id.name)?.layoutParams?.width = maxTitleWidth
}
}
}
-
著重看一下我圈起來的幾個地方
- 首先創(chuàng)建widthMeasureSpec, heightMeasureSpec, 也就是調(diào)用View.measre()方法的兩個參數(shù)
- 遍歷集合創(chuàng)建出對應(yīng)的子item
- 調(diào)用view的measure方法, 這樣就能測出左邊title的寬度了
- 通過計算纪铺,將最大的title寬度保存到maxTitleWidth
- 遍歷所有的child,將左邊的title控件的寬度改成maxTitleWidth
以上5步就能實現(xiàn)所給的效果圖了突诬。