美文网首页
View的测量问题

View的测量问题

作者: wjploop | 来源:发表于2019-08-27 15:38 被阅读0次

    我们知道,onMeasure(int widthMeasureSpec, int heightMeasureSpec) 方法中,测量当前视图的大小,需要考虑父视图传给的参数限制。那么要不理睬父容器的限制(即不用上述方法中的两个参数),自己确定大小会有什么问题呢?

    回答这个问题,我们需要明白一些前置知识。

    由于一个View一般是不会单独存在的,通常会嵌套在其他ViewGroup中,要是子View绘制区域超出父View给出大小时,是要截断的(这里有例外情况,在父View中,将clipChildren设置为false,子View绘制区域可以超出)。

    例子:

    class ChildView :View {
        
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {     
            //无视父视图传来的参数,直接给当前View设置宽高
           setMeasureDimension(400, 400)
        }
         override fun onDraw(canvas: Canvas) {
            //简单涂个颜色
            canvas.drawColor(Color.BLUE)
        }
    }
    
    class ParentView:ViewGroup{
        init{
              addChild(ChildView(context))
        }
        override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
            
            val child = getChildAt(0)
            //一般情况下,我们是要先要根据child的测量大小,padding来放置的,
            //为了简单,不管padding
           //我们作为父视图,有权如何防止子View。要求子View大小小于200,这个限制在onMeasure中传递给子View
            child.layout(0, 0, 200, 200)
        }
    
          override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {     
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    
            //这里给子View传递一个测量参数,从而调用子View的onMeasure()方法    
            //从而告知子View的大小应该100的,否则父View没法好好处理
            val child = getChildAt(0)
            val measureSpec=MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY)
            child.measure(measureSpec,measureSpec)
      
        }
    }
    

    从上面的例子中看,在子View的测量过程中,父视图需要调用child.measure(),将一些大小要求传递给子View的,子View在onMeasure()方法中,获取参数,在父View的布局要求范围内,设置子View的测量大小。无论是哪一方不遵循着个契约, 都会造成布局错乱的可能。

    相关文章

      网友评论

          本文标题:View的测量问题

          本文链接:https://www.haomeiwen.com/subject/grgsectx.html