自定义View常见问题

总结一下自定义view:

1.执行顺序

onMeasure()——-onLayout()——onDraw();

注意:onLayout()一般 自定义view 中 可以不写,因为:我们在布局中可以直接定义位置

2.onMeasure()方法中的两个参数

前两位是测量模式,后两位是测量的值
模式分为
1.UNSPECIFIED:父容器没有对当前View有任何限制,当前View可以任意取尺寸

2.EXACTLY:当前的尺寸就是当前View应该取的尺寸 。 对应的是我们布局中的 match_layout 或者 是 直接给的准确值 如:150dp

3.AT_MOST:当前尺寸是当前View能取的最大尺寸 。 对应的是我们布局中的 wrap_cantent

我们默认的的模式是EXACTLY

我们可以通过3种方式 给onMeasure 方法设置 你需要展示的宽高 ,这三种方式 分别对应不同的情况。

第一种
用户在布局中写什么,我们根据判断来获取

  private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text
            result = switch_background.getWidth();
            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by
                // measureSpec
                result = Math.min(result, specSize);
            }
        }

        return result;
    }

最后在:

  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      //通过判断把传入的值设置进去  setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));

    }

第二种:
直接调用setMeasuredDimension(),把我们需要让他多宽多高设置进去,这里设置之后。无论在xml里面 怎么规定,都不会影响 你通过该方法设置的宽高

setMeasuredDimension(switch_background.getWidth(),switch_background.getHeight());

第三种:
写一个方法,让调用者来设置:
1.直接传入值,不需要通过第一种方式来判断

 setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);

2.然后我们通过向外提供方法来控制

  public  void setWandH(int with,int height){
        ViewGroup.LayoutParams params = getLayoutParams();
        params.width=with;
        params.height=height;
        setLayoutParams(params);
    }

执行完之后 会自动回调onMeasure()

3.关于getWith() 和getMearsureWith()区别:

简单来说getWith() 是我们能看见的高度,getMearsureWith()是空间实际的高度。
举个例子:
我手机屏幕宽200, 这是我有个控件宽是300,那么getwith 获取的值就是200, getMearsureWith 获取的值就是300

注意一点:getWith()只能在onlayout()方法执的执行完之后 才能获取,getMearsureWith() 在onMeasure()的setMeasuredDimension执行完之后就能获取。 在activity 中,onMearsure(),方法在onResurm()方法之后才执行,也就是说onResurm()之前包括onResurm()是无法获取 控件的宽高的。

如果想获取怎么办: 如下3个方法可以获取到

1. 在 onWindowFocusChanged 可以得到
2. 
mTv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        System.out.println("onGlobalLayout: "+mTv.getHeight());
        mTv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
    }
});
3. 
mTv.post(new Runnable() {
    @Override
    public void run() {
        System.out.println("run: "+mTv.getHeight());
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值