自定义View常见问题

来源:互联网 发布:caffe经典模型实战pdf 编辑:程序博客网 时间:2024/05/01 14:53

总结一下自定义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
原创粉丝点击