Android getWidth和getMeasuredWidth的正解+layout_weigth使用正解


转自http://hi.baidu.com/ljlkings/home

一。也许很多童鞋对getWidth()和getMeasuredWidth()的用法:getWidth得到是某个view的实际尺寸. getMeasuredWidth是得到某view想要在parent view里面占的大小
                     

二。
1.在一个类初始化时,即在构造函数当中我们是得不到View的实际大小的。感兴趣的朋友可以试一下,getWidth()和getMeasuredWidth()得到的结果都是0.但是我们可以从onDraw()方法里面得到控件的大小。
2.这两个方法所得到的结果的单位是像素即pixel. 
对两个方法做介绍:getWidth():得到的是view在父Layout中布局好后的宽度值,如果没有父布局,那么默认的父布局是整个屏幕。也许不好理解。通过一个例子来说明一下。

例1 :public class Test extends Activity {  

private LinearLayout mBackgroundLayout; 

 private TextViewTest mTextViewTest;
 

 /** Called when the activity is first created. */ 
 @Override 
 public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState);

  mBackgroundLayout = new MyLayout(this); 
  mBackgroundLayout.setLayoutParams(new LinearLayout.LayoutParams( 
    LinearLayout.LayoutParams.FILL_PARENT, 
    LinearLayout.LayoutParams.FILL_PARENT));

  mTextViewTest = new TextViewTest(this);

  mBackgroundLayout.addView(mTextViewTest); 
  setContentView(mBackgroundLayout); 
 } 
 public class MyLayout extends LinearLayout{

  public MyLayout(Context context) { 
   super(context); 
   // TODO Auto-generated constructor stub 
  }

  @Override 
  protected void onLayout(boolean changed, int l, int t, int r, int b) { 
   // TODO Auto-generated method stub 
   super.onLayout(changed, l, t, r, b); 
   Log.i(" Tag", "--------------"); 
   View mView=getChildAt(0); 
   mView.measure(0, 0); 
  } 

 } 


 public class TextViewTest extends TextView {   

      public TextViewTest(Context context) {   

          super(context);   

          // TODO Auto-generated constructor stub   

          setText("test test ");  

      }   

     @Override   

       protected void onDraw(Canvas canvas) {    

       super.onDraw(canvas);   

       // measure(0, 0);   

        Log.i("Tag", "width: " + getWidth() + ",height: " + getHeight());   

        Log.i("Tag", "MeasuredWidth: " + getMeasuredWidth()      + ",MeasuredHeight: " + getMeasuredHeight());   

       }

 } 

这里是在LinearLayout里添加一个TextView控件,如果此时要得到对TextView获取getWidth(),那么是在TextView添加到Layout后再去获取值,并不单单的是对TextView本身宽度的获取。getMeasuredWidth():先看一下API里面怎么说的 The width of this view as measured in the most recent call to measure(). This should be used during measurement and layout calculations only. 得到的是在最近一次调用measure()方法测量后得到的view的宽度,它仅仅用在测量和layout的计算中。所以此方法得到的是view的内容占据的实际宽度。你如果想从一个最简单的例子中的到它们的不同,下面将对上面的例子做一下修改:

public class Test extends Activity {  

     private TextViewTest mTextViewTest;

 /** Called when the activity is first created. */ 
    @Override 
     public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mTextViewTest = new TextViewTest(this); 
      setContentView(mTextViewTest); 
 }

 public class TextViewTest extends TextView { 
  public TextViewTest(Context context) { 
   super(context); 
   // TODO Auto-generated constructor stub 
   setText("test test "); 
  }

  @Override 
  protected void onDraw(Canvas canvas) { 
   // TODO Auto-generated method stub 
   super.onDraw(canvas); 
   measure(0, 0); 
   Log.i("Tag", "width: " + getWidth() + " ,height: " + getHeight()); 
   Log.i("Tag", "MeasuredWidth: " + getMeasuredWidth() 
     + ",MeasuredHeight: " + getMeasuredHeight()); 
  } 
 } 

总结(正解):getWidth(): View在设定好布局后整个View的宽度。  getMeasuredWidth():对View上的内容进行测量后得到的View内容占据的宽度,前提是你必须在父布局的onLayout()方法或者此View的onDraw()方法里调用measure(0,0);( measure参数的值你可以自己定义),否则你得到的结果和getWidth()得到的结果一样。       也许我组织的不是很好,大家有什么不清楚的地方再给我留言。关于这两个方法的区别就是看你有没有用measure()方法,当然measure()的位置也是很重要的。
 

 

-------------------------------------------------- ------------------2011/03/01更新-------------------------- ----------------------------------

1. 在xml里面用的Layout_weight是什么意思?

 A: 该属性代表的权值,权值越小,级别越高,即在布局中占的分量就越重,举例。

       <?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android=" http://schemas.android.com/apk/res/android " 
    android:orientation="horizontal" 
    android:layout_width ="fill_parent" 
    android:layout_height="fill_parent" 
    > 
<Button 
 android:layout_width="fill_parent" 
 android:layout_height="wrap_content" 
 android:layout_weight="1" 
 android:text="Button1" 
 /> 
<Button 
 android:layout_width= "fill_parent" 
 android:layout_height="wrap_content" 
 android:layout_weight="2" 
 android:text="Button2" 
 /> 
</LinearLayout>

因为设置了button1的权重最小,所以它占用的布局就越大,这样设置的意思是:将横向的布局分为三份,button1占两份,button2占一份,很简单的,有什么不懂的可以留言,谢谢!,

下面看效果图:

*******2011-3-26 修改

       这里要首先感谢sunwayforever的指导,避免了我这篇文章错误之处的进一步扩散,在这里先引用一句话吧:由于作者水平有限,文章中难免有疏漏和错误之处,恳请大家批评指正。谢谢!(注:上面绿色底纹的言论错误,希望大家往下看)
这里对layout_weight说一下自己新的见解,首先,前面有一句话“因为设置了button1的权重最小,所以它占用的布局就越大”这句话在你的layout_width设置为fill_parent的时候是没错的,可是如果设置为wrap_content的时候,这句话就解释不清了,下面是sunwayforever对此属性的认识:

linearLayout中包含有weight的child时,linearLayout会measure两次:
设屏幕宽度为X 
第一次:button1的measuredWidth为X,button2也为X (因为用了weight,所以linearLayout每次measure child时不考虑前一个已经占用的大小),total_width为2X 
第二次:计算delta=x-total_width=-x,然后会将button1的宽度设为
x+delta*1/3=0.66x, button2的宽度为x+delta *2/3=0.33x

      那我现在对这句话重新概括一下:“因为设置了button1的权重最小,所以它占用的布局优先级就越高”,也许在Android里面布局并没有优先级之说,我这里只是为了说明问题,自己定义的,所以朋友们不要拍砖。
      那首先分析一下当layout_width属性设置为fill_parent的时候,即充满父布局,当然意思是这个控件要根据weight的设置尽可能的大,因此,依上例而论,button1的weight设为1,button2的weight设置为2.即button的优先级最高,因此,要填充父布局就要button1先来填充,尽可能的大,那这个尽可能又是多少呢,这就要综合layout里其他控件的weight值了,然后做一下运算,button1占据2/3,button2占据1/3.你也可以把button2设置为一个非常大的数,比如2000,此时在Graphical Layout模式下可以看到button1填充满了整个宽度,而看不到button2的影子,事实上button2还是存在的,你把鼠标指向button1的后面就可以看到一个长长的竖条,那个就是button2,已经非常非常小了。因此,在layout_width设置为fill_parent的时候,weight所代表的是你的控件要优先尽可能的大。


     接着是当layout_weight设置为wrap_content的时候,即适应内容的宽度,意思是这个控件要尽可能的小,只要能把内容显示出来就可以了,同样的,如果把button1和button2的layout_weight设置为wrap_content后,button1的weight为1,button2的weight为2.那么button1要优先尽可能的小,而button2也要尽可能的小,只是优先级不一样,因为设置了weight,所以这两个控件总的宽度要填满父布局的宽度,所以就又要计算每个控件所占据的大小,此时,button1的优先级较高,共有两份,一份1/3,一份2/3,button1要尽可能的小,那button1当然要选1/3,因此,我们看到的效果反而是button2占据的较大。这里要说的是如果把权值同样做如下设置:button1为1,button2为2000,那button1是不是就要占据1/2000的空间呢?这么理解就错了,刚才说了,要尽可能的小,但这个小是有一个限度的,那就是wrap_content,就是还要是内容完完整整的显示出来,同样的,尽可能的大也是有一个限度的,那就是父布局的宽度。因此,在layout_width设置为wrap_content的时候,weight所代表的是你的控件要优先尽可能的大。

所以,要对weight做了解,要深深的理解下面两句话:在layout_width设置为fill_parent的时候,layout_weight所代表的是你的控件要优先尽可能的大,但这个大是有限度的,即fill_parent. 在layout_width设置为wrap_content的时候,layout_weight所代表的是你的控件要优先尽可能的小,但这个小是有限度的,即wrap_content.

layout_height 同layout_width.

 

下面贴几张图:

1. layout_width="fill_parent", button1的weight=1,button2的weight=2;


2.layout_width="fill_parent", button1的weight=1,button2的weight=2000;


3.layout_width="wrap_content", button1的weight=1,button2的weight=2;


4.layout_width="wrap_content", button1的weight=1,button2的weight=2000;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值