android获取控件宽度高度
2015-10-02 10:48
417 查看
前几天,在自定义控件的时候碰到个问题,就是在如何获取自定义控件的高宽。在自定义控件类的构造函数中,本来以为可以轻松获取,但事实不是这样。我测试了下面代码:
先是布局代码:
<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);这一条,这个可以保证系统运行一次。
先是布局代码:
<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);这一条,这个可以保证系统运行一次。
相关文章推荐
- Android英语单词记忆程序源码
- 在Android中可以使用Gson解析JSON数据
- [Android Pro] 内容提供者ContentProvider的基本使用
- Android 程序打包及签名
- 利用半透明对话框实现新浪微博android客户端首次运行时的提示界面
- Android仿真翻页
- Android 触摸屏幕产生小气泡的效果源码
- Android TextView 文字飞入效果
- Android 随手势滑动销毁(finish)Activity
- Android Studio之导入Project
- Android高级部分常见问题
- Android知识体系
- Android开发之多级下拉列表菜单实现(仿美团,淘宝等)
- Android初中级阶段——一个新的开始,新的起点
- 如何替换android apk中的so
- Android目录(更新中)
- 转载android 规范技巧
- android通讯录开发及优化
- Android Api Demos登顶之路(八十六)Graphics-->Regions
- Android Api Demos登顶之路(八十五)Graphics-->PurgeableBitmap