在開發中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");