Android自定义ViewGroup多行多列效果

本文实例为大家分享了Android自定义ViewGroup多行多列的具体代码,供大家参考,具体内容如下

先看下效果图

每行两个子孩子

每行一个子孩子

实现思路

自定义viewGroup,实现测量和布局,使控件适应业务场景。

测量

根据父控件的宽度,平均分给每个子孩子固定的宽度。高度就是行数乘以一个子孩子的高度,再加上空隙的高度。

根据子孩子个数计算行数  

val rows = if (childCount % perLineChild == 0) {

childCount / perLineChild

} else {

childCount / perLineChild + 1

}

代码示例

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

val width = MeasureSpec.getSize(widthMeasureSpec)

for (i in 0 until childCount) {

val child: View = getChildAt(i)

if (child.visibility != GONE) {

val lp = child.layoutParams

val childWidthMeasureSpec = getChildMeasureSpec(

widthMeasureSpec,

0, (width - (perLineChild - 1) * space) / perLineChild

)

val childHeightMeasureSpec = getChildMeasureSpec(

heightMeasureSpec,

0, lp.height

)

child.measure(childWidthMeasureSpec, childHeightMeasureSpec)

}

}

val rows = if (childCount % perLineChild == 0) {

childCount / perLineChild

} else {

childCount / perLineChild + 1

}

if (childCount > 0) {

setMeasuredDimension(

width,

getChildAt(0).measuredHeight * rows + (rows - 1) * space

)

}

}

布局

需要注意摆放的顺序和位置,每行摆放固定的个数,达到个数之后换行继续摆放

代码示例 

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {

var left = l

var top = t

children.forEachIndexed { index, view ->

if (index % perLineChild == 0) {

left = 0

if (index != 0) {

top += view.measuredHeight

top+=space

}

view.layout(left, top, view.measuredWidth + left, top + view.measuredHeight)

} else {

view.layout(left, top, view.measuredWidth + left, top + view.measuredHeight)

}

left += view.measuredWidth

left += space

}

}

完整代码

class MultiLineViewG @JvmOverloads constructor(

context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0

) : ViewGroup(context, attrs, defStyleAttr) {

var perLineChild = 2

/**

* 子孩子之间的空隙

*/

var space = 10

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

val width = MeasureSpec.getSize(widthMeasureSpec)

for (i in 0 until childCount) {

val child: View = getChildAt(i)

if (child.visibility != GONE) {

val lp = child.layoutParams

val childWidthMeasureSpec = getChildMeasureSpec(

widthMeasureSpec,

0, (width - (perLineChild - 1) * space) / perLineChild

)

val childHeightMeasureSpec = getChildMeasureSpec(

heightMeasureSpec,

0, lp.height

)

child.measure(childWidthMeasureSpec, childHeightMeasureSpec)

}

}

val rows = if (childCount % perLineChild == 0) {

childCount / perLineChild

} else {

childCount / perLineChild + 1

}

if (childCount > 0) {

setMeasuredDimension(

width,

getChildAt(0).measuredHeight * rows + (rows - 1) * space

)

}

}

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {

var left = l

var top = t

children.forEachIndexed { index, view ->

if (index % perLineChild == 0) {

left = 0

if (index != 0) {

top += view.measuredHeight

top+=space

}

view.layout(left, top, view.measuredWidth + left, top + view.measuredHeight)

} else {

view.layout(left, top, view.measuredWidth + left, top + view.measuredHeight)

}

left += view.measuredWidth

left += space

}

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android自定义ViewGroup多行多列效果 的全部内容, 来源链接: utcz.com/p/243885.html

回到顶部