android布局優(yōu)化

android布局優(yōu)化的目標:

  • 使屏幕繪制低延遲
  • 保證流程穩(wěn)定的幀率來避免卡頓

優(yōu)化布局的技巧:

  • 減少布局層次
    下圖是一個簡單的app View,其中包含一些View。搭建這些view的時候,一定要留意屏幕右上角的組件樹(Component Tree)。套嵌的子view越深,組件樹就越復雜,渲染起來也就越費時間。

對于app里的每一個view,android系統(tǒng)都會經(jīng)過三部曲來渲染:measure,layout,draw??梢栽谀X中回想下你搭建的view的xml布局文件結構,measure從最頂部的節(jié)點開始,順著layout樹形結構依次往下:測量每個view需要在屏幕當中展示的尺寸大小。每個子節(jié)點都需要向自己的父節(jié)點提供自己的尺寸來決定展示的位置,遇到?jīng)_突的時候,父節(jié)點可以強制子節(jié)點重新measure(由此可能導致measure的時間消耗為原來的2-3倍)。這就是為什么扁平的view結構會性能更好。節(jié)點所處位置越深,套嵌帶來的measure越多,計算就會越費時。

  • 刪除無用布局
  • 不要嵌套多個使用layout_weight屬性的LinearLayout
  • Android lint
  • Hierarchy Viewr
  • <merge />
    什么情況考慮使用Merge?
    子視圖不需要指定任何針對父視圖的布局屬性,例子中TextView僅僅需要直接添加到父視圖上用于顯示就行。例子:
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.kevinwang.test.TestActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="Test Merge!"/>
</RelativeLayout>

圖1是使用RelativLayout時顯示的層次結構。


圖1

布局文件修改內(nèi)容如下:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.kevinwang.test.TestActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="Test Merge!"/>
</merge>

圖2是使用merge時顯示的層次結構。

圖2

Merge標簽有什么使用限制?
只能作為XML布局的根標簽使用。

  • ViewStub標簽
    ViewStub 是一個隱藏的,不占用內(nèi)存空間的視圖對象,它可以在運行時延遲加載布局資源文件。例子:
    先來創(chuàng)建一個Activity中使用的布局文件,文件名是:activity_test.xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.kevinwang.test.TestActivity">

    <Button
        android:id="@+id/show_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="顯示"/>

    <ViewStub
        android:id="@+id/viewstub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout="@layout/sub_layout"
        />

    <Button
        android:id="@+id/hide_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="隱藏"/>
</LinearLayout>

android:layout="@layout/sub_layout"引入一個新的布局sub_layout.xml代碼如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <TextView  xmlns:android="http://schemas.android.com/apk/res/android"
               android:id="@+id/textview"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="ViewStub中包含的TextVeiw"/>
</LinearLayout>

添加Button點擊事件:

public class TestActivity extends Activity {
    private Button showButton;
    private Button hideButton;
    private ViewStub viewStub;
    private View view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

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

        showButton = (Button)findViewById(R.id.show_button);
        showButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (view == null) {
                    view = viewStub.inflate();//注意inflate方法不能被調(diào)用兩次
                }
                else {
                    view.setVisibility(View.VISIBLE);
                }
            }
        });

        hideButton =(Button)findViewById(R.id.hide_button);
        hideButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                view.setVisibility(View.GONE);
                if (view == null) {
                    Log.i("hide_layout", "隱藏布局已經(jīng)消失");
                }
            }
        });
    }
}

打開應用時界面如下圖:



點擊顯示按鈕時界面如下:



點擊隱藏恢復打開應用時的界面

關于布局優(yōu)化更多內(nèi)容可參考MrPeakTech

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容