在Android开发中,有时候,为了适配不同的屏幕,使得UI看上去美观,就需要根据当前的屏幕尺寸来动态地添加视图。一般分为三个步骤:
1.新建组件;
2.获得父视图尺寸;
3.根据父视图尺寸,计算将要添加的子视图的尺寸和坐标位置,根据这些参数建立父视图的布局参数(LayoutParam),并将子视图添加到父视图中。
下面用一个例子来说明——在一个RelativeLayout中动态添加一个Button。
一 获得xml中的RelativeLayout,新建Button
RelativeLayout relativeLayout = (RelativeLayout)findViewById(R.id.relativeLayout);
Button btn = new Button(getApplicationContext());
二 获得父视图尺寸
double parentWidth = relativeLayout.getWidth();
double parentHeight = relativeLayout.getHeight();
注意事项:如果在onCreate()或者onResume()方法中调用父视图的getWidth()和getHeight()方法,返回的值为0。这是因为父视图(以及别的视图)还没有完成绘制,必须等待系统绘制完父视图时,才能去调用这两个方法获得父视图最终的尺寸。所以解决的办法就是等待父视图绘制完成之后,再去调用getWidth()和getHeight(),和进行后续的步骤。这里介绍一个方法——将一个runnable添加到父视图队列中的方法:View.post(),作者是kissazi2:
作者:kissazi2
出处:http://www.cnblogs.com/kissazi2/
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
runnable对象中的方法会在View的measure、layout等事件后触发,具体的参考Romain Guy:
UI事件队列会按顺序处理事件。在setContentView()被调用后,事件队列中会包含一个要求重新layout的message,所以任何你post到队列中的东西都会在Layout发生变化后执行。
这个方法的优点在于:
1、runnable里面的代码只会执行一次
2、语法很简单
思路代码如下:
final View view=//smth;
...
view.post(new Runnable() {
@Override
public void run() {
view.getHeight(); //height is ready
}
});
具体到本例中这么写:
relativeLayout.post(new Runnable() {
@Override
public void run(){
double parentWidth = relativeLayout.getWidth();
double parentHeight = relativeLayout.getHeight();
后续的各种操作。。。。
}
}):
三 根据父视图尺寸计算将要添加的子视图的尺寸和坐标位置,根据这些参数建立父视图的布局参数(LayoutParam),将子视图添加到父视图中
double btnHeight = ****;
double btnWidth = ****;
RelativeLayout.LayoutParams btnParam =new RelativeLayout.LayoutParams((int) btnHeight, (int) btnWidth); //初始化父视图布局参数,设置Button的大小
btnParam.leftMargin= ****; //Button距离父视图左边界的距离
btnParam.topMargin= ****; //Button距离父视图顶部的距离
relativeLayout.addView(btn, btnParam); //根据子视图在父视图中的布局参数,将子视图添加到父视图中
到此为止,Button就被动态地添加到RelativeLayout中了。