android:layout_weight的巧妙应用(二)

之前我讲过layout_weight的巧妙应用一 http://www.cnblogs.com/xiaoQLu/archive/2011/08/08/2130328.html 

现在更深入讲下weight的其他应用和原理

先看下图,我要用LinearLayout实现如下效果,2要自适应大小,也就是wrap_content,1要占满剩下的空间怎么办?(当然用相对布局很简单)

如果我要再实现一个更变态点的需求呢,就是2位置要动态变换呢(右图所示效果),根据不同的状态,设置2位置不同控件的隐藏和显示,这种情况下,用RelativeLayout实现就有点麻烦了,你要找到一个基准控件,然后根据他来布局其他控制,如果有一个设置不对,显示的布局就没有这个效果

先分析此问题的难点:

  (1)控件2的宽度不确实的,导致1不知道自己的宽度要设为多少。

  (2)控件2的位置有多个控件,需要动态控制不同控件来显示和隐藏

如果用LinearLayout就简单很多,linearlayout有一个属性,就是本篇的主角android:layout_weight属性,它是属于LinearLayout特有的。

     

 

用LinearyLayout实现有两种写法,都差不多。写提供代码

实现一
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/hello" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" /> </LinearLayout>
实现二
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <Button
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/hello" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name" />

</LinearLayout>

其实这两种实现只有一点区别,就是第一个button的layout_weidth,一个是fill_parent,另一个是0dip。其实两种都差不多,下边详细讲解:

首先大家要明白一个概念,就是一个控件(View)本身是可以无限大的,也说是说在它自己的onDraw()函数中,你想要它多大,它就可以有多大,但是为什么我们只能看到一部分呢?

这就要"归功"于android:layout_width和height属性,很多人认为这个是设置控制本身大小的,其实这个理解有偏差,layout_width这个属性不是控制一个子控件它本身的大小(自身大小由它

自己决定),而是父布局提供给这个控件的显示窗口大小,这里叫申请大小(下面同理)

 然后来讲解详细的计算过程,当LinearLayout包含的视图weight>0时,它会mesure两次(这里以上面第一个布局来讲解)

第一次,计算剩余空间,就是用屏幕的宽度减去子控件申请的宽度。设屏幕宽度为TW,第一个button的申请宽度设为x1,weight为w1,第二个button的申请宽度设为x2,weight为w2,剩余空间设为delta

表达示为 delta = TW - (x1+x2)

第二次,分配空间,即父视图最终提供给子控件的显示窗口的大小,

button1的最终显示大小为   x1+delta*w1/(w1+w2)

button2的最终显示大小为   x2+delta*w2/(w1+w2)

 结合上面的实例来说明

上面第一个布局,假设手机分辨率为480x320,btn1申请宽度为fill_parent=320,btn2的申请宽度为wrap_content,这个是会调用控件自身的onMeasure计算出来的,假设计算结果为40,那么

第一步剩余空间就是320-(320+40) = -40,

第二步,分配空间,btn1的最终显示空间为320+(-40)*(1/(1+0)) = 280,btn2的最终显示空间为40+(-40*0/(1+0)) = 40

这样就满足了我们开始的那个需求,

再分析第一个布局,其实本质和第一个布局一样,只是把减去变为加上而已

第一步,剩余空间 = 320-(0+40) = 280;

第二步,分配 btn1最终空间 0+280*1/(1+0) = 280,btn2的最终空间为40+280*0/(0+1)

 

 

posted @ 2012-09-20 15:55  muzhi121  阅读(1769)  评论(0编辑  收藏  举报