android中LayoutParams設置參數的理解


1. 有這樣的一個應用場景:有一個linearLayout控件在其中布局一個textView控件

    

首先,創建線性布局對象

 LinearLayout layout = new LinearLayout(this);//為本Activity創建一個線性布局對象
//並且設置它的屬性 android:layout_width 與 android:layout_height 都為 FILL_PARENT
//布局方面的屬性設置方式
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT);

 

然后,為本Activity創建一個TextView,代碼如下

TextView textView = new TextView(this);
//然后設置TextView的屬性
textView.setText(R.string.hello);
textView.setId(34);

對於布局方面的屬性這樣來設置

 LinearLayout.LayoutParams textviewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
      ViewGroup.LayoutParams.WRAP_CONTENT);

接着在線性布局對象中加入這個TextView

layout.addView(textView,textviewParams);//加入的同時,也就設置了TextView相對於布局對象的布局屬性 android:layout_width 與 android:layout_height
最后一步,設置本Activity的頂級界面為線性布局
setContentView(layout,layoutParams); //同時也就設置了布局對象的android:layout_width 與 android:layout_height

個人猜想:控件的屬性分為 控件自身特性屬性 與布局屬性:即與父控件的關系屬性.

 

LayoutParams的理解與應用:

       LayoutParams相當於一個Layout的信息包,它封裝了Layout的位置、高、寬等信息。假設在屏幕上一塊區域是由一個Layout占領的,如果將一個View添加到一個Layout中,最好告訴Layout用戶期望的布局方式,也就是將一個認可的layoutParams傳遞進去。
       可以這樣去形容LayoutParams,在象棋的棋盤上,每個棋子都占據一個位置,也就是每個棋子都有一個位置的信息,如這個棋子在4行4列,這里的“4行4列”就是棋子的LayoutParams。

       但LayoutParams類也只是簡單的描述了寬高,寬和高都可以設置成三種值:
       1,一個確定的值;
       2,FILL_PARENT,即填滿(和父容器一樣大小);
       3,WRAP_CONTENT,即包裹住組件就好。

 

在JAVA中動態構建的布局,常常這樣寫:

setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

上面這一句話其實是子對父的,也就是說,父布局下的子控件要設置這句話。

因為布局很多,雖然都繼承至ViewGroup但是各個布局還是有很大的不同。

很顯然上面這句應該這樣寫才算准確:

setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT,TableRow.LayoutParams.FILL_PARENT));

下面分別說下兩個常用到布局:

1. FrameLayout下動態設置子控件居中,動態用JAVA代碼要這樣實現:

FrameLayout.LayoutParams lytp = new FrameLayout.LayoutParams(80,LayoutParams.WRAP_CONTENT);
lytp .gravity = Gravity.CENTER;
btn.setLayoutParams(lytp);

2. RelativeLayout下動態設置子控件居中:

RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); 
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE); 
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE); 
btn1.setLayoutParams(lp);

 

 

在實際開發中LayoutInflater這個類還是非常有用的,它的作用類似於findViewById()。
不同點是LayoutInflater是用來找res/layout/下的xml布局文件,並且實例化;
而findViewById()是找xml布局文件下的具體widget控件(如Button、TextView等)。
 
具體作用:
1、對於一個沒有被載入或者想要動態載入的界面,都需要使用LayoutInflater.inflate()來載入;
2、對於一個已經載入的界面,就可以使用Activiyt.findViewById()方法來獲得其中的界面元素。
LayoutInflater 是一個抽象類,在文檔中如下聲明:
public abstract class LayoutInflater extends Object
獲得 LayoutInflater 實例的三種方式
1. LayoutInflater inflater = getLayoutInflater();//調用Activity的getLayoutInflater() 
2. LayoutInflater inflater = LayoutInflater.from(context);  
3. LayoutInflater inflater =  (LayoutInflater)context.getSystemService
                              (Context.LAYOUT_INFLATER_SERVICE);
其實,這三種方式本質是相同的,從源碼中可以看出:
getLayoutInflater():
Activity 的 getLayoutInflater() 方法是調用 PhoneWindow 的getLayoutInflater()方法,看一下該源代碼:
public PhoneWindow(Context context)
{   
 super(context);   
    mLayoutInflater = LayoutInflater.from(context);
}
可以看出它其實是調用 LayoutInflater.from(context)。
LayoutInflater.from(context):
public static LayoutInflater from(Context context)
{   
 LayoutInflater LayoutInflater = (LayoutInflater) context.getSystemService
         (Context.LAYOUT_INFLATER_SERVICE);
    if (LayoutInflater == null)
    {       
     throw new AssertionError("LayoutInflater not found.");   
    }   
    return LayoutInflater;
}
 
可以看出它其實調用 context.getSystemService()。
 
結論:所以這三種方式最終本質是都是調用的Context.getSystemService()。
 
另外getSystemService()是Android很重要的一個API,它是Activity的一個方法,根據傳入的NAME來取得對應的Object,然后轉換成相應的服務對象。
 
以下介紹系統相應的服務。
 
傳入的Name 返回的對象 說明
WINDOW_SERVICE WindowManager 管理打開的窗口程序
LAYOUT_INFLATER_SERVICE LayoutInflater 取得xml里定義的view
ACTIVITY_SERVICE ActivityManager 管理應用程序的系統狀態
POWER_SERVICE PowerManger 電源的服務
ALARM_SERVICE AlarmManager 鬧鍾的服務
NOTIFICATION_SERVICE NotificationManager 狀態欄的服務
KEYGUARD_SERVICE KeyguardManager 鍵盤鎖的服務
LOCATION_SERVICE LocationManager 位置的服務,如GPS
SEARCH_SERVICE SearchManager 搜索的服務
VEBRATOR_SERVICE Vebrator 手機震動的服務
CONNECTIVITY_SERVICE Connectivity 網絡連接的服務
WIFI_SERVICE WifiManager Wi-Fi服務
TELEPHONY_SERVICE TeleponyManager 電話服務
inflate 方法
通過 sdk 的 api 文檔,可以知道該方法有以下幾種過載形式,返回值均是 View 對象,如下:
public View inflate (int resource, ViewGroup root) 
public View inflate (XmlPullParser parser, ViewGroup root)
public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)  
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
示意代碼:
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);       
View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));       
//EditText editText = (EditText)findViewById(R.id.content);// error 
EditText editText = (EditText)view.findViewById(R.id.content);
對於上面代碼,指定了第二個參數 ViewGroup root,當然你也可以設置為 null 值。
注意:
·inflate 方法與 findViewById 方法不同;
·inflater 是用來找 res/layout 下的 xml 布局文件,並且實例化;
·findViewById() 是找具體 xml 布局文件中的具體 widget 控件(如:Button、TextView 等)。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM