美文网首页Android学习笔记 - UI
自定义View-计算控件尺寸

自定义View-计算控件尺寸

作者: CoderYuZ | 来源:发表于2019-04-24 13:40 被阅读0次

    本文主要是自己学习的笔记,想学习的建议直接去看HenCoder视频教学地址

    不同于上一篇:修改控件尺寸,有些时候需要自己计算控件尺寸而不是修改已经计算好的,所以在重写onMeasure的时候,就不需要调用super. onMeasure(),直接自己去算好宽高,然后setMeasuredDimension设置进去就好了。

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            ...
            // 自定义宽高
            width = ...;
            height = ...;
    
            // 过滤宽高(检查宽高是否合格)
            width = resolveSize(width, widthMeasureSpec);
            height = resolveSize(height, heightMeasureSpec);
    
            // 设置宽高
            setMeasuredDimension(width, height);
        }
    

    上面代码有很重要的一步:resolveSize(),因为控件并不是想自己大多就能多大,我们算好的尺寸,或者说希望的尺寸,并不一定能成为最后的尺寸,比如父控件空间不足。所以要调用resolveSize去过滤一下,resolveSize是View中已经实现了的方法,点击去看下具体做了什么事情,resolveSize的代码大致如下:

        // resolveSize的简化实现,并不是完整源码
        public static int resolveSize(int size, int measureSpec){
            
            final int specMode = MeasureSpec.getMode(measureSpec);
            final int specSize = MeasureSpec.getSize(measureSpec);
            final int result;
            
            switch (specMode) {
                case MeasureSpec.AT_MOST:
                    if (specSize < size) {
                        result = specSize;
                    } else {
                        result = size;
                    }
                    break;
                case MeasureSpec.EXACTLY:
                    result = specSize;
                    break;
                case MeasureSpec.UNSPECIFIED:
                default:
                    result = size;
            }
            return result ;
        }
    

    在onMeasure中的两个参数widthMeasureSpec、heightMeasureSpec并不只包含了size,还包含了mode,mode只指父控件对其的限制,有三种AT_MOST(最大值)、EXACTLY(精确值)、UNSPECIFIED(无限制)。

    resolveSize方法分析:

    调用resolveSize过滤其实就是根据mode计算出准确的size返回,而并非子控件想自己多大就大多。
    size:我们计算出来的值,也可以说是子控件自己希望的值。
    specSize:从onMeasure的参数中获取的,是父控件调用子控件的measure()方法的时候传入的,是父控件对子控件的限制。

    • 当mode是AT_MOST,就是父控件规定了子控件的最大值,specSize就是这个最大值,所以:
    return Math.min(size, specSize)
    
    • 当mode为EXACTLY,就是父控件要精确的控制子控件大小,子控件的大小必须是specSize,所以:
    return specSize
    

    当mode为UNSPECIFIED,也就是父控件对子控件没限制,子控件的大小可以为其自己希望的大小,所以:

    return size
    

    感谢HenCoder

    相关文章

      网友评论

        本文标题:自定义View-计算控件尺寸

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