Android 自定义ViewGroup addView,视图不刷新
     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一次性全部显示到界面上。

3个回答

看看这个有没有帮助 http://blog.csdn.net/zhanglongit/article/details/42459199
另外可以看看强仔老师的Android自定义View课程,有问题还可以向老师提问http://www.atstudy.com/course/142

sfw673306004
龟兔赛竞走 虽然并没有解决我的问题,我只是为了关闭提问罢了,我的bug产生的原因是由于,视图改变父容器宽高未改变的情况下,onLayout方法中的changed参数为false,新换行时高度改变该值才变为true,所以不加这个布尔值判断的条件就行了。
2 年多之前 回复

你这是布局的问题,改一下你的布局文件

    @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;
                }
            }
//        }
    }

它说的是这。就是哪行小字里说的。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!