1. 程式人生 > >安卓效能優化—佈局優化

安卓效能優化—佈局優化

效能優化是開發中必不可少的,大概可以從記憶體、佈局以及app啟動時間等方面進行優化,本篇文章介紹一些佈局優化的方法;

A RelativeLayout is a very powerful utility for designing a user interface because it can eliminate nested view groups and keep your layout hierarchy flat, which improves performance. If you find yourself using several nested LinearLayout groups, you may be able to
replace them with a single RelativeLayout.

Google的意思是 RelativeLayout 在效能上更好,但是在開發中還是要根據實際情況選擇適當的佈局;
1. RelativeLayout 佈局靈活一些儘量使用padding代替margin;
2. 實現複雜的佈局時,由於 RelativeLayout 所需要的巢狀層次少,所以可能大概也許效能會好一些。
3. 對於簡單的佈局,或者使用 LinearLayout 的巢狀佈局層次不多的情況下。還是推薦 使用 inearLayout 來實現。 因為 LinearLayout 佈局效能更高一點,為什麼? 因為 RelativeLayout 佈局需要至少計算兩次。

2.使用include標籤
include標籤常用於將佈局中的公共部分提取出來,達到xml檔案複用的效果;

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
>
<include layout="@layout/test_layout" /> </RelativeLayout>

3.使用merge標籤
merge標籤是作為include標籤的一種輔助擴充套件來使用,它的主要作用是為了防止在引用佈局檔案時產生多餘的佈局巢狀。Android渲染需要消耗時間,佈局越複雜,效能就越差。如上述include標籤引入了之前的LinearLayout之後導致了介面多了一個層級。

item_merge_layout佈局:

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

    <ImageView        
        android:id="@+id/iv_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:src="@mipmap/ic_launcher" />

    <TextView      
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="16dp"
        android:layout_toRightOf="@+id/iv_image"
        android:text="這個是MergeLayout"
        android:textSize="16sp" />
</merge>

activity_main佈局中使用include標籤:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jared.layoutoptimise.MainActivity">

    <include layout="@layout/test_layout" />
</RelativeLayout>

在item_merge_layout佈局中使用了merge標籤,所以此時activity_main佈局會減少一層原來test_layout的最外層佈局;
4、使用viewstub標籤
viewstub是view的子類。他是一個輕量級View, 隱藏的,沒有尺寸的View。他可以用來在程式執行時簡單的填充佈局檔案。接著簡單試用下viewstub吧。首先修改activity_main.xml檔案如下:

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

    <include        
        android:id="@+id/layout_merge"
        layout="@layout/item_merge_layout" />

    <ViewStub       
        android:id="@+id/vs_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout="@layout/item_merge_layout"
        android:layout_below="@+id/layout_merge"
        android:layout_marginTop="10dp" />
</RelativeLayout>

使用ViewStub標籤時要注意 ViewStub只能被inflate一次,否則會丟擲ViewStub must have a non-null ViewGroup viewParent異常;

Android最新的佈局方式ConstaintLayout
ConstraintLayout允許你在不適用任何巢狀的情況下建立大型而又複雜的佈局。它與RelativeLayout非常相似,所有的view都依賴於兄弟控制元件和父控制元件的相對關係。但是,ConstraintLayout比RelativeLayout更加靈活,目前在AndroidStudio中使用也十分方便,就和以前的拖拉控制元件十分相似。那麼怎麼使用呢?
  首先是安裝Constaintlayout了。Android SDK -> SDK Tools -> Support Repository中的ConstrainLayout for Android和Solver for ConstaintLayout。
新增依賴:

compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'

接下來就可以輕鬆愉快的使用ConstaintLayout實現你的xml佈局了;

  1. TextView同時顯示圖片和文字
<TextView
        android:drawableLeft="@drawable/icon_1"
        android:drawableRight="@drawable/icon_2"
        android:drawablePadding="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"        
        android:text="聯絡人"      
        android:gravity="center_vertical"        
        android:layout_height="50dp" />

2 TextView的行間距

<TextView
        android:textSize="14dp"
        android:lineSpacingExtra="8dp"
        android:gravity="center_vertical"
        android:text="攬件方式:上門取件\n快遞公司:順豐快遞\n預約時間:9月6日 立即取件\n快遞費用:等待稱重確定價格"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

lineSpacingExtra屬性代表的是行間距,他預設是0,是一個絕對高度值。同時還有lineSpacingMultiplier屬性,它代表行間距倍數,預設為1.0f,是一個相對高度值。
3. 使用Spannable或Html.fromHtml實現富文字;

 String text = String.format("¥%1$s  門市價:¥%2$s", 18.6, 22);
 int z = text.lastIndexOf("門");
 SpannableStringBuilder style = new SpannableStringBuilder(text);
 style.setSpan(new AbsoluteSizeSpan(DisplayUtil.dip2px(mContext,14)), 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //字號
 style.setSpan(new ForegroundColorSpan(Color.parseColor("#afafaf")), z, text.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //顏色
 style.setSpan(new AbsoluteSizeSpan(DisplayUtil.dip2px(mContext,14)), z, text.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //字號

 tv.setText(style);

4.用LinearLayout自帶的分割線

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:divider="@drawable/divider"
    android:showDividers="middle">

    <TextView
        android:drawableLeft="@drawable/icon_1"
        android:drawableRight="@drawable/icon_4"
        android:drawablePadding="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textSize="16sp"
        android:text="我的卡券"
        android:background="@color/white"
        android:gravity="center_vertical"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <TextView
        android:drawableLeft="@drawable/icon_2"
        android:drawableRight="@drawable/icon_4"
        android:drawablePadding="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textSize="16sp"
        android:text="地址管理"
        android:background="@color/white"
        android:gravity="center_vertical"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <TextView
        android:drawableLeft="@drawable/icon_3"
        android:drawableRight="@drawable/icon_4"
        android:drawablePadding="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textSize="16sp"
        android:text="檢查更新"
        android:background="@color/white"
        android:gravity="center_vertical"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

</LinearLayout>

現的核心部分其實是LinearLayout的這兩行:

android:divider="@drawable/divider"
android:showDividers="middle"

其中divider.xml是分隔線樣式:

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

    <size android:width="1dp"
          android:height="1dp"/>

    <solid android:color="#e1e1e1"/>

</shape>

showDividers 是分隔線的顯示位置,beginning、middle、end分別代表顯示在開始位置,中間,末尾。

還有dividerPadding屬性這裡沒有用到,意思很明確給divider新增padding;