View 的 getWidth 和 getMeasuredWidth() 有什么区别;
区别问题先看源码
getMeasuredWidth 的源码
public static final int MEASURED_SIZE_MASK = 0x00ffffff;
public final int getMeasuredWidth() {
//掩码只看前两位后面的
return mMeasuredWidth & MEASURED_SIZE_MASK;
}
private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight;
mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
}
mMeasuredWidth & MEASURED_SIZE_MASK 获取后六位,是measure阶段结束后 view 的真实值
public final int getWidth() {
return mRight - mLeft;
}
在 layout 阶段调用 setOpticalFrame()在调用 setFrame 的方法中设置,表示 view 在页面中的最终大小
2. 如何在onCreate() 拿到 View 的宽度和高度。
window对象并没有创建完成只是做了出事货操作,要获得控件尺寸要等到控件 onDraw 执行之后,一般通过下面3种方法解决
1. 通过 view 类 getViewTreeObserver 为控件添加观察者当获得正确的宽高后,请移除这个观察者,否则回调会多次执行
“`
tv.getViewTreeObserver().addOnPreDrawListener(){
public boolean onPreDraw(){
if(!hasDraw){
Log.e(TAG,tv.getMeasuredWidth()+"=="+tv.getMeasuredHeight());
hasDraw =true;
}
return true;
}
}
```
2. 监听 view 可是状态变化,view 绘制之后,可是状态会发生改变添加addOnGlobalLayoutListener来监听
```
tv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.e(TAG,tv.getMeasuredWidth()+"=="+tv.getMeasuredHeight());
}
});
“`
3. 重新执行一次view 的onMeasure 方法
```
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ImageView imageView = (ImageView) findViewById(R.id.imageview);
//------------------------------------------------方法一
int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
imageView.measure(w, h);
int height =imageView.getMeasuredHeight();
int width =imageView.getMeasuredWidth();
textView.append("\n"+height+","+width);
System.out.println("执行完毕.."+System.currentTimeMillis());
}
“`
第三种会多执行一次onMeasure,第一种要加被重复调用的处理,一般使用第二种方法