本篇旨再使用kotlin代码实现TextView的流式排版,采用继承于ViewGroup的形式进行构建。
流式布局采用的方式是由左至右,右上至下的形式。简单的理解就是textview先排满一行后,再排下一行。按照此方式,我们可以确定,每一行应该由一个TextView的集合,同时也应该会确定一个统一的行高:
/** * 行视图集合 */ class FlowChips { /** * 子视图 */ var views: MutiableList<View> = mutableListOf() /** * 行高 */ var rowHeight: Int = 0 }
以下开始实现FlowLayout:
class FlowLayout : ViewGroup { private val DEBUG: Boolean = false private val TAG: String = "FlowLayout" /** * 列间隔 */ private var mHorizontalSpacing: Int = 10 /** * 行间隔 */ private var mVerticalSpacing: Int = 10 private val chipArray: MutableList<FlowChips> = ArrayList<FlowChips>() constructor(context: Context?) : super(context) constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( context, attrs, defStyleAttr ) constructor( context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int ) : super(context, attrs, defStyleAttr, defStyleRes) @SuppressLint("DrawAllocation") override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { chipArray.clear() val selfWidth = MeasureSpec.getSize(widthMeasureSpec) val selfHeight = MeasureSpec.getSize(heightMeasureSpec) val selfHeightMode = MeasureSpec.getMode(heightMeasureSpec) val selfWidthMode = MeasureSpec.getMode(widthMeasureSpec) var rowChips = FlowChips() var rowHeight: Int = 0; var rowWidthUsed: Int = 0; var totalHeight: Int = 0; for (i in 0 until childCount) { val childView = getChildAt(i) val lp = childView.layoutParams val childWidthMeasureSpec = getChildMeasureSpec(MeasureSpec.makeMeasureSpec(selfWidth, selfWidthMode), childView.paddingStart + childView.paddingEnd, lp.width) val childHeightMeasureSpec = getChildMeasureSpec(MeasureSpec.makeMeasureSpec(selfHeight, selfHeightMode), childView.paddingTop + childView.paddingBottom, lp.height) childView.measure(childWidthMeasureSpec, childHeightMeasureSpec) var rowHeightTemp = rowHeight; rowHeightTemp = rowHeightTemp.coerceAtLeast(childView.measuredHeight) var widthUsedTemp = rowWidthUsed widthUsedTemp += childView.measuredWidth if (widthUsedTemp > selfWidth) { // 超过父View宽度 // 此行结束,换行 totalHeight += rowHeight + mVerticalSpacing; chipArray.add(rowChips) rowChips = FlowChips() rowWidthUsed = childView.measuredWidth rowHeight = childView.measuredHeight rowChips.rowHeight = rowHeight; rowChips.views.add(childView) } else { rowWidthUsed = widthUsedTemp + mHorizontalSpacing rowChips.rowHeight = rowHeightTemp; rowChips.views.add(childView) } if (i == childCount - 1) { totalHeight += rowHeight + mVerticalSpacing rowChips.rowHeight = rowChips.rowHeight.coerceAtLeast(rowHeight) chipArray.add(rowChips) } } setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(totalHeight.coerceAtLeast(selfHeight), selfHeightMode)) } override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { var currentLeft = paddingStart var currentTop = paddingTop for(chips in chipArray) { for(view in chips.views) { var start = currentLeft; var top = currentTop; var end = start + view.measuredWidth var bottom = top + view.measuredHeight view.layout(start, top, end, bottom) currentLeft = end + mHorizontalSpacing } currentLeft = paddingStart currentTop += chips.rowHeight + mVerticalSpacing } } }
完结
标签:childView,val,Int,Kotlin,布局,流式,rowChips,var,rowHeight From: https://www.cnblogs.com/swalka/p/16808381.html