源码下载:http://download.csdn.net/detail/forwardyzk/7271971
转载请注明原文地址:http://blog.csdn.net/forwardyzk/article/details/24730733
一般情况下,我们都是在文件中设置好长和宽,使用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); }
/** * 第二种方法:动态的设置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); }
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