class AutoArrangeLayout(context: Context, attrs: AttributeSet?) : ViewGroup(context, attrs) {
var horizontalSpacing: Int = 0
set(value) {
field = value
requestLayout()
}
var verticalSpacing: Int = 0
set(value) {
field = value
requestLayout()
}
init {
val ta = context.obtainStyledAttributes(attrs, R.styleable.AutoArrangeLayout)
horizontalSpacing = ta.getDimensionPixelSize(R.styleable.AutoArrangeLayout_horizontalSpacing, 20)
verticalSpacing = ta.getDimensionPixelSize(R.styleable.AutoArrangeLayout_verticalSpacing, 20)
ta.recycle()
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
if (changed) {
(0..childCount)
.asSequence()
.map { getChildAt(it) }
.forEach {
it?.let {
val get = map[it]
if (get != null) {
it.layout(get.x, get.y, get.x + it.measuredWidth, get.y + it.measuredHeight)
}
}
}
}
}
var map: HashMap<View, Point> = HashMap()
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var length = paddingLeft
var rowHeight = 0
var lastLineHeight = paddingTop + verticalSpacing
map.clear()
(0..childCount).
map { getChildAt(it) }
.forEach {
it?.let {
measureChild(it, widthMeasureSpec, heightMeasureSpec)
if (it.measuredWidth + length + horizontalSpacing + paddingLeft + paddingRight <= measuredWidth) {
val point = Point()
length += horizontalSpacing
point.x = length
point.y = lastLineHeight
map.put(it, point)
length += it.measuredWidth
rowHeight = Math.max(it.measuredHeight, rowHeight)
} else {
length = horizontalSpacing + paddingLeft
lastLineHeight += rowHeight + verticalSpacing
val point = Point()
point.x = length
point.y = lastLineHeight
map.put(it, point)
length += it.measuredWidth
rowHeight = it.measuredHeight
}
}
}
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
var calcHeightMeasureSpec = heightMeasureSpec
if (heightMode == MeasureSpec.AT_MOST) {
calcHeightMeasureSpec = MeasureSpec.makeMeasureSpec(lastLineHeight + rowHeight + verticalSpacing, MeasureSpec.EXACTLY)
}
super.onMeasure(widthMeasureSpec, calcHeightMeasureSpec)
}
}
上述是自定义ViewGroup的类代码,是一个自动排列布局.
测试的时候在界面上还有个btn,点击一次会调用一次该类实例的addView方法,但是发现如果addView后,在该类的高设为wrap的情况下,如果高不足以新换一行则addView添加的视图不显示,若足够新换一行,则会连同之前添加的未显示的view一次性全部显示到界面上。
看看这个有没有帮助 http://blog.csdn.net/zhanglongit/article/details/42459199
另外可以看看强仔老师的Android自定义View课程,有问题还可以向老师提问http://www.atstudy.com/course/142
你这是布局的问题,改一下你的布局文件
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
// if (changed) {
int childLeft = 0;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View childView = getChildAt(i);
if (childView.getVisibility() != View.GONE) {
final int childWidth = childView.getMeasuredWidth();
childView.layout(childLeft, 0,
childLeft + childWidth, childView.getMeasuredHeight());
childLeft += childWidth;
}
}
// }
}
它说的是这。就是哪行小字里说的。