天天看點

Android 布局優化之include

在開發中UI布局是我們都會遇到的問題,随着UI越來越多,布局的重複性、複雜度也會随之增長。Android官方給了幾個優化的方法,但是網絡上的資料基本上都是對官方資料的翻譯,這些資料都特别的簡單,經常會出現問題而不知其是以然。這篇文章就是對這些問題的更詳細的說明,也歡迎大家多留言交流。

一、include

首先用得最多的應該是include,按照官方的意思,include就是為了解決重複定義相同布局的問題。例如你有五個界面,這五個界面的頂部都 有布局一模一樣的一個傳回按鈕和一個文本控件,在不使用include的情況下你在每個界面都需要重新在xml裡面寫同樣的傳回按鈕和文本控件的頂部欄, 這樣的重複工作會相當的惡心。使用include标簽,我們隻需要把這個會被多次使用的頂部欄獨立成一個xml檔案,然後在需要使用的地方通過 include标簽引入即可。其實就相當于C語言、C++中的include頭檔案一樣,我們把一些常用的、底層的API封裝起來,然後複用,需要的時候 引入它即可,而不必每次都自己寫一遍。示例如下 :

my_title_layout.xml

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:id="@+id/my_title_parent_id"  
    android:layout_height="wrap_content" >  

    <ImageButton  
        android:id="@+id/back_btn"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:src="@drawable/ic_launcher" />  

    <TextView  
        android:id="@+id/title_tv"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_centerVertical="true"  
        android:layout_marginLeft="20dp"  
        android:layout_toRightOf="@+id/back_btn"  
        android:gravity="center"  
        android:text="我的title"  
        android:textSize="18sp" />  

</RelativeLayout>  
           

include布局檔案:

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical" >  

    <include  
        android:id="@+id/my_title_ly"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        layout="@layout/my_title_layout" />  

    <!-- 代碼省略 -->
</LinearLayout>  
           

這樣我們就可以使用my_title_layout了。

注意事項

  • 使用include最常見的問題就是findViewById查找不到目标控件,這個問題出現的前提是在include時設定了id,而在 findViewById時卻用了被include進來的布局的根元素id。例如上述例子中,include時設定了該布局的id為 my_title_ly,而my_title_layout.xml中的根視圖的id為my_title_parent_id。此時如果通過 findViewById來找my_title_parent_id這個控件,然後再查找my_title_parent_id下的子控件則會抛出空指針。代碼如下 :
View titleView = findViewById(R.id.my_title_parent_id) ;  
// 此時 titleView 為空,找不到。此時空指針
 TextView titleTextView = (TextView)titleView.findViewById(R.id.title_tv) ;  
titleTextView.setText("new Title");  
           

其正确的使用形式應該如下:

// 使用include時設定的id,即R.id.my_title_ly
View titleView = findViewById(R.id.my_title_ly) ;  
// 通過titleView找子控件
TextView titleTextView = (TextView)titleView.findViewById(R.id.title_tv) ;  
titleTextView.setText("new Title"); 
           

或者更簡單的直接查找它的子控件:

TextView titleTextView = (TextView)findViewById(R.id.title_tv) ;  
titleTextView.setText("new Title");