Android 佈局巧用之include、merge、ViewStub

原文連接:https://mp.weixin.qq.com/s/bTA2gztUzqvqER2rz56RRQandroid

相信你們常常聽到includemergeViewStub這樣的標籤,官方也提到這三種佈局可用於佈局的優化。今天就介紹下這三種佈局的使用,記錄下來,便於後續app中的使用。git

include佈局重用

app開發過程當中,會遇到不一樣頁面裏有相同的佈局,這時咱們能夠將這些通用的佈局提取出來到一個單獨的layout文件裏,再使用<include>標籤引入到相應的頁面佈局文件裏,主要經過includelayout屬性引用。
舉個栗子
include的佈局:github

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

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="這裏是來自include佈局" />

</RelativeLayout>

activity的佈局:微信

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

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="如下的內容來自include標籤" />

    <include
        android:id="@+id/container"
        layout="@layout/include_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv"
        android:layout_marginTop="10dp" />

</RelativeLayout>

這個標籤在平常工做使用仍是很常見的。這裏有幾點須要注意下:
一、若是給include標籤 和 include所加載的佈局 都添加id的話,那麼id要保持一致,如例子中都是container,不然是在代碼中獲取不到RelativeLayout容器的。 固然咱們能夠避免這樣的問題,只須要給其中一項添加id屬性就能夠。app

二、include佈局裏元素的id 要和 include所在頁面佈局裏的其餘元素id 不一樣,如例子中的兩個textview,若是把id設置相同了,程序運行起來並不會報錯,可是textview的賦值只會賦值給其中的一個。佈局

三、若是須要給include標籤設置位置屬性的話,如例子中的layout_belowlayout_marginTop,這時候 必須 同時設置include標籤的寬高屬性layout_widthlayout_height,不然編譯器是會報錯的。通常狀況不須要設置include的其餘屬性,直接加載佈局文件 <include layout="@layout/...."/>優化

四、佈局中能夠包含兩個相同的include標籤,以下代碼所示 兩個include都加載layout="@layout/include_layout"3d

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

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="如下的內容來自include標籤" />

    <include
        android:id="@+id/container"
        layout="@layout/include_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv"
        android:layout_marginTop="10dp" />

    <include
        android:id="@+id/container2"
        layout="@layout/include_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp" />

</RelativeLayout>

能夠設置不一樣include的id屬性,引用的時候以下能夠正常顯示:code

View view = findViewById(R.id.container2);
TextView textView = view.findViewById(R.id.tv);
textView.setText("這裏是來自 第二個 include佈局");

merge減小視圖層級

merge標籤可用於減小視圖層級來優化佈局,能夠配合include使用,若是include標籤的父佈局 和 include佈局的根容器是相同類型的,那麼根容器的能夠使用merge代替。
頁面佈局xml

<?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">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="如下的內容不是來自merge標籤" />

    <include
        layout="@layout/merge_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp" />

</LinearLayout>

先看沒有使用merge的:

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

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="這裏是否是來自merge佈局" />

</LinearLayout>

看下view層的結構:

再看使用了merge的:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="這裏是來自merge佈局" />

</merge>

view層結構:

能夠看到對比,減小了一層的LinearLayout的嵌套,須要注意的是使用merge的佈局,在include的標籤設置距離屬性沒有生效,能夠將一些間距屬性設置到include佈局裏元素上,具體看項目需求使用。

ViewStub按需加載

按需加載 顧名思義須要的時候再去加載,不須要的時候能夠不用加載,節約內存使用。一般狀況咱們會使用setVisibility方法來控制視圖的顯示和隱藏,可是這種狀況視圖已經加載了。
好比app中頁面裏某個佈局只須要在特定的狀況下才顯示,其他狀況下能夠不用加載顯示,這時候能夠使用ViewStub
layout屬性是須要加載佈局

<?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">

    <ViewStub
        android:id="@+id/viewstub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout="@layout/viewstub_layout" />

</LinearLayout>

須要注意的是 ViewStubinflate()方法只能被調用一次,一旦調用後,ViewStub將從視圖中移除,被對應的layout佈局取代,同時會保留ViewStub上設置的屬性效果。

ViewStub viewstub = findViewById(R.id.viewstub);
viewstub.inflate();

這篇關於includemergeViewStub的使用就介紹到這裏了,具體使用狀況還得視項目而定。

最後附上github地址https://github.com/taixiang/include

歡迎關注個人博客:https://blog.manjiexiang.cn/
更多精彩歡迎關注微信號:春風十里不如認識你
image.png

相關文章
相關標籤/搜索