您的位置:首页 > 其它

动态的获取和设置控件的长和宽

2014-04-29 18:19 218 查看
源码下载:http://download.csdn.net/detail/forwardyzk/7271971

转载请注明原文地址:/article/9441959.html

一般情况下,我们都是在文件中设置好长和宽,使用match_parent,warp_content,fill_parent和设置固定的长和宽,倘若有这样的一种情况,使用代码设置控件的长和宽,那么这样就会根据动态获取控件的大小,按比例的设置其他控件的常何况,这样也可以达到屏幕适配的效果。

这只是一种情况,还有其他的情况用到动态的获取或者设置控件的长和宽。

获取控件的长和宽

我们一般情况下,会在onCreate()中用到这种办法获取控件的长和宽。

int w=findViewById(R.id.ll).getWidth(); 我们发现这样获得的宽度是0,原因是:在onCreate()方法获得的控件对象还没有开始测量,所以获得的宽度是0,当执行了onMeasure()方法,才可以获得真正的宽,然后执行onDraw()方法,展示出来。

main.xml

<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<TextView
android:id="@+id/tv_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff0000"
android:text="this is 01" />

<TextView
android:id="@+id/tv_02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff00ff"
android:text="this is 02" />
</LinearLayout>


那么怎样在onCreate()方法中获得长和宽呢。有以下三种方法:

方法1:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ll = (LinearLayout)findViewById(R.id.ll);
tv_01 = (TextView)findViewById(R.id.tv_01);
tv_02 = (TextView)findViewById(R.id.tv_02);

int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
ll.measure(w, h);
int width = ll.getMeasuredWidth();
int height = ll.getMeasuredHeight();
Log.i(TAG, "方法1:"+String.valueOf(width)+":"+height);
}


介绍:

在main.xml中,LinearLayout是填充的父窗体,但是使用此方法获取的宽度却不是屏幕的宽度。而是两个TextView实际长度的和。Log.i(TAG, "屏幕的宽度:"+getWindowManager().getDefaultDisplay().getWidth());

方法2:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ll = (LinearLayout)findViewById(R.id.ll);
tv_01 = (TextView)findViewById(R.id.tv_01);
tv_02 = (TextView)findViewById(R.id.tv_02);

ViewTreeObserver vto = ll.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
int height = ll.getMeasuredHeight();
int width = ll.getMeasuredWidth();
Log.i(TAG, "方法2:"+String.valueOf(width)+":"+height);
//w = width;
//setWidth_01(ll.getMeasuredWidth());
return true;
}
});
Log.i(TAG, "屏幕的宽度:"+getWindowManager().getDefaultDisplay().getWidth());
}
介绍:

使用此方法获得的宽度是设置的长度

如果你设置的是填充父窗体,那么获得的宽度是屏幕的宽度

如果你设置的是一个具体的宽度(200),那么获得的宽度是设置的那个值(200)

方法3:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ll = (LinearLayout)findViewById(R.id.ll);
tv_01 = (TextView)findViewById(R.id.tv_01);
tv_02 = (TextView)findViewById(R.id.tv_02);

ViewTreeObserver vto2 = ll.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ll.getViewTreeObserver().removeGlobalOnLayoutListener(this);
Log.i(TAG, "方法3:"+String.valueOf(ll.getWidth())+":"+ll.getHeight());
}
});
Log.i(TAG, "屏幕的宽度:"+getWindowManager().getDefaultDisplay().getWidth());
}


介绍:

此方法和方法二获得的值是一样的。

动态的设置控件的长和宽

方法1:

/**
* 第一种方法:动态的设置View的宽和高
*/
public void setWidth_01(int w) {
LinearLayout.LayoutParams llp = new LayoutParams(w, 50);
tv_01.setLayoutParams(llp);
}


方法2:

/**
* 第二种方法:动态的设置View的宽和高
*/
public void setWidth_02(int w) {
// 第二种设置控件的宽度
LinearLayout.LayoutParams llp = null;
llp = (LayoutParams)tv_02.getLayoutParams();
llp.width = w;
tv_02.setLayoutParams(llp);

}


这两种方法动态的设置控件的长和宽效果是一样的。

注意点:

1.如果是使用第一种方法获得的宽度,然后动态的设置长和宽,此时的长和宽是控件中实际内容所占的常何况

2.如果使用第二种方法获得长和宽

直接设置的话,那么会出现死循环,虽然效果出来了,可以通过查看打印的log就明白是死循环。

public void getWidth_02() {
ViewTreeObserver vto = ll.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
int height = ll.getMeasuredHeight();
int width = ll.getMeasuredWidth();
Log.i(TAG, "方法2:"+String.valueOf(width)+":"+height);
setWidth_01(ll.getMeasuredWidth());
return true;
}
});
}


如果是把获得的长和宽设置为成员变量,那么在设置的话,获取的长和宽是0

public void getWidth_02() {
ViewTreeObserver vto = ll.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
int height = ll.getMeasuredHeight();
int width = ll.getMeasuredWidth();
Log.i(TAG, "方法2:"+String.valueOf(width)+":"+height);
w=width;
return true;
}
});
setWidth_01(w);
}


3.如果是第三种方法获取长和宽,是没有异常状况的。

public void getWidth_03() {
ViewTreeObserver vto2 = ll.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ll.getViewTreeObserver().removeGlobalOnLayoutListener(this);
Log.i(TAG, "方法3:"+String.valueOf(ll.getWidth())+":"+ll.getHeight());
setWidth_01(ll.getWidth());
}
});
}
也可以把长和宽提取为成员变量,然后给其他控件设置长和宽也可以。

综上所述:

如果只是获得长和宽,那么获取长和宽的方法1和方法2都可以,根据需要选取。

如果即获取还要设置,那么推荐使用方法3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: