前几天,在自定义控件的时候碰到个问题,就是在如何获取自定义控件的高宽。在自定义控件类的构造函数中,本来以为可以轻松获取,但事实不是这样。我测试了下面代码:
先是布局代码:
<com.lml.getvalues.MyView
android:id="@+id/myView"
android:layout_width="match_parent"
android:layout_height="150px"
android:background="#ff0000" />
再是MyView的构造函数的代码:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
a="在MyView构造函数中 : MeasuredWidth:"+this.getMeasuredWidth()+";"+"MeasuredHeight:"+this.getMeasuredHeight()+";"
+"Width:"+this.getWidth()+";"+"Height:"+this.getHeight()+"\n";
String h="",w="";
for(int i =0 ;i < attrs.getAttributeCount();i++){
if("layout_height".equals(attrs.getAttributeName(i))){
h=attrs.getAttributeValue(i);
}else if("layout_width".equals(attrs.getAttributeName(i))){
w=attrs.getAttributeValue(i);
}
}
b="在构造函数attrs中 : width:"+w+";"+"height:"+h+"\n";

}

编译得到a="在MyView构造函数中 : MeasuredWidth:0;MeasuredHeight:0;Width:0;Height:0".
b="在构造函数attrs中 : width:-1;height:150.0px

结果显示当width为match_parent等数值时,只显示-1等,不能满足我的需求。

然后我试着在相应Activity的onCreate中获取高宽,获得的全部是0.但我在onCreate中的加了个点击控件获取高宽事件,能正确获取高宽。我在网上查了下资料,因为在onCreate中控件还未被度量,所以获取肯定为0.网上有获取三个方法,方法如下:
方法一,在onCreate中添加如下代码:
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
myView.measure(w, h);
int height = myView.getMeasuredHeight();
int width = myView.getMeasuredWidth();
tvValues.append("方法一: height:"+height + ",width:" + width+"\n");

方法二可以实现,代码如下:
ViewTreeObserver vto2 = myView.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
myView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
tvValues.append( "方法二: height:"+myView.getHeight() + ",width:" + myView.getWidth()+"\n");
}
});
但我发现removeGlobalOnLayoutListener在API 级别 16 开始已经废弃,如果去掉,系统会读取多次。

再来看看方法三,代码如下:

ViewTreeObserver vto = myView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
myView.getViewTreeObserver().removeOnPreDrawListener(this);
int height = myView.getMeasuredHeight();
int width = myView.getMeasuredWidth();
tvValues.append("方法三: height:"+height + ",width:" + width + "..\n");
return true;
}
});
我在网上资料的基础上添加了myView.getViewTreeObserver().removeOnPreDrawListener(this);这一条,这个可以保证系统运行一次。

更多相关文章

  1. Android编程获取地理位置的经度和纬度实例
  2. Android(安卓)7.0 ActivityManagerService(1) AMS的启动过程
  3. Android电池驱动
  4. Android(安卓)SurfaceFlinger 学习之路(五)----VSync 工作原理
  5. Android(安卓)8.1移植:针对某个APK做到wifi和gprs分别做到允许和
  6. 获取Android手机的图片和视频的缩略图[转]
  7. Android获取常用辅助方法(获取屏幕高度、宽度、密度、通知栏高度
  8. Android弹出DatePickerDialog并获取值的方法
  9. android动态获取权限方法

随机推荐

  1. Android辅助功能
  2. Android(安卓)中进程、Activity、Boradca
  3. 【专家专栏】Android中的防缓冲区溢出技
  4. Android(安卓)动态设置TextView的drawabl
  5. 如何修改Android5.1系统音量大小
  6. Android中 Lottie库初步实践与应用场景分
  7. Android之——使用Android(安卓)studio创
  8. 这是一篇描述 Broadcasts 的文章
  9. Android(安卓)Application Digital Signa
  10. Android(安卓)SpannableString 设置文字