2 sfw673306004 sfw673306004 于 2017.01.16 16:36 提问

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一次性全部显示到界面上。

2个回答

qq_36590778
qq_36590778   2017.01.16 17:22
已采纳

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

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

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

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
Android View刷新机制
一:总体说明 在Android的布局体系中,父View负责刷新、布局显示子View;而当子View需要刷新时,则是通知父View来完成。 二:代码分析 1).ViewGroup的addView方法,理解参数的意义和传递 invalidate调用父类View的方法 addViewInner方法主要做的事情是 view的dispatchAttachedToWindow(Atta
Android5.0后的ViewGroup添加子View问题
前些日子我一直被这个问题困扰,就是ViewGroup调用addView的ChildView的绘制层问题。我之前在CSDN上进行了提问,可惜没有人回答我。最近,我又想起了这个问题,我又进行精简探索。之前的问题的地址:http://ask.csdn.net/questions/376400现象我在Layout文件下编写以下代码:<FrameLayout xmlns:android="http://sch
Android7.0 自定义控件addView(...)无效,View的绘制流程(onMeasure、onLayout等)完全没执行的解决办法。
问题描述昨天在写一个自定义控件的时候遇到一个问题,就是我通过addView(View child) 方法添加View之后再7.0上没有显示出来,6.0上没有问题。通过AS自带的Layout Inspector工具检查发现我的自定义控件的宽高都是0,并且getVisibility()==VISIBLE,也就是说控件是显示的,只是没有宽高所以看不到。 先看下我addView的代码吧:void setF
android viewGroup中addView使用方式及其粗解
addView是继承viewGroup的方法, void android.view.ViewGroup.addView(View child); void android.view.ViewGroup.addView(View child, LayoutParams params); void android.view.ViewGroup.addView(View child, int
viewgroup中删除和添加子view
定义一个view,此处虽然是view,但是通过inflate一个layout后,实际上是一个viewgroup,直接通过强转就可以当成viewgroup使用 View tab01; tab01 = inflater.inflate(R.layout.tab01, null); 触发改变view的内容,则删除原有的所有子view,从新add一个layout作为其子view: ((Vi
ViewGroup和View的理解和当子视图发生更新时通知viewgroup更新
1. 概念 Android中的View与我们以前理解的“视图”不同。在Android中,View比视图具有更广的含义,它包含了用户交互和显示,更像Windows操作系统中的window。 ViewGroup是View的子类,所以它也具有View的特性,但它主要用来充当View的容器,将其中的View视作自己的孩子,对它的子View进行管理,当然它的孩子也可以是ViewGroup类型。
在一个ViewGroup中添加子view
所有的Android中的控件都是继承于View,ViewGroup也不例外。在ViewGroup中有个addView的方法能动态的添加一个子view。 这个是一个简单的例子,能在代码中动态的添加一个子view: package com.example.foreveross.myapplication; import android.graphics.Color; import androi
android自定义viewGroup 不显示问题
欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I 引用 Ctrl
ViewGroup的方法addView的使用
一、前导 ViewGroup是View的子类,
android ViewGroup删除子视图时应该注意的一个问题
在Activity中创建一个LinearLayout,创建一个scrollHorizon对象(scrollHorizon继承自ViewGroup),在scrollHorizon中调用createLayout函数来加载myView(继承自View)对象,然后调用deleteAllView函数来删除所有的视图。 scrollHorizon代码: public class scrollHoriz