1. 程式人生 > >Android圖層妙用之layer-list的基本使用介紹

Android圖層妙用之layer-list的基本使用介紹

1. layer-list 是啥?有啥作用?

1.1 layer-list 是什麼?

簡單理解,layer 是層,list 是列表,那麼 layer-list 就是層列表的意思。但是,是什麼層列表呢?? 其實 layer-list 是用來建立 LayerDrawable 的,LayerDrawable 是 DrawableResource 的一種, 所以,layer-list 創建出來的是 圖層列表,也就是一個drawable 圖形。

1.2 layer-list 用途

上面已經說過,layer-list 是用來建立 圖層列表的,通過它能創建出一些特殊的 drawable, 比如:
下圖 AlertDialog 中,我們只需要設定 button 的 頂部邊線,以及 左側button的右邊線(或者右側button的左邊線),這種時候我們就無法直接使用 shape 了,因為直接使用 shape 繪製出來的是四個邊框; 如果讓美工切圖也可以,但那樣的話靈活度就差了很多,而且會增加app的體積;這種情況下,使用 layer-list 就是最佳選擇。當然,layer-list 的用途還有很多,這裡只是舉一個例子,具體的使用請繼續往下看。


這裡寫圖片描述

2. layer-list 的大致原理

layer-list 的大致原理類似 RelativeLayout(或者FrameLayout) ,也是一層層的疊加 ,後新增的會覆蓋先新增的。在 layer-list 中可以通過 控制後新增圖層距離最底部圖層的 左上右下的四個邊距等屬性,得到不同的顯示效果。

上面示例圖中,AlertDialog 底部的 ok按鈕 的背景就是用layer-list實現的。該layer-list 中,底層使用一個填充色為藍色 的shape,上層使用一個填充色為白色的shape ,然後控制上層距離最底層的頂部邊距為1dp , 這樣在視覺上就形成了一個 具有藍色頂部邊線的白色背景。具體程式碼繼續往下看。

3. layer-list 基本使用示例:

因 layer-list 創建出來的也是 drawable 資源,所以,同 shape selector 一樣,都是定義在 res 中的 drawable 資料夾中,也是一個 xml 檔案。使用的時候,同shape selector , 佈局檔案中使用 @drawable/ xxx 引用, 程式碼中使用 R.drawable.xxx 引用。

layer-list 中不同的圖層使用 item 節點來定義。

3.1 效果1 :單一邊線

效果圖:

圖中,TextView 只有一個頂部邊線
這裡寫圖片描述
具體程式碼:

  • 建立帶有藍色頂部邊線的 layer-list 圖

在 res 目錄中的 drawable 目錄下,建立名稱為 singleline.xml 的xml 檔案,然後編輯 layer-list 的詳細程式碼,如下:

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

    <!--底層使用藍色填充色-->
    <item>
        <shape>
            <solid android:color="#02a0ef"/>
        </shape>
    </item>

    <!--上面一層距離底層的頂部1dp,類似marginTop,填充色為白色,這樣就形成了一個帶有藍色頂部邊線的白色背景的圖-->
    <item android:top="1dp">
        <shape>
            <solid android:color="#fff"/>
        </shape>
    </item>
</layer-list>
  • 使用 layer-list 圖,設定為textView的背景
 <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@drawable/singleline"
        android:gravity="center"
        android:text="單一邊線效果"/>

3.2 效果2 :雙邊線

效果圖:

圖中,TextView 具有上下邊線
這裡寫圖片描述
具體程式碼:

  • 建立帶有藍色頂部和底部邊線的 layer-list 圖
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!--底層使用藍色填充色-->
    <item>
        <shape>
            <solid android:color="#02a0ef"/>
        </shape>
    </item>

    <!--上面一層距離底層的頂部1dp,距離底部1dp,類似marginTop,填充色為白色,這樣就形成了一個帶有藍色頂部邊線和底部邊線的白色背景的圖-->
    <item android:bottom="1dp"
          android:top="1dp">
        <shape>
            <solid android:color="#fff"/>
        </shape>
    </item>
</layer-list>
  • 使用 layer-list 圖,設定為textView的背景
<TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/doubleline"
        android:gravity="center"
        android:text="雙邊線效果"/>

3.3 效果3:陰影

效果圖:
這裡寫圖片描述
具體程式碼:

  • 建立 layer-list
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!--底層的左邊距離上層左邊3dp, 底層的頂部,距離上層的頂部6dp,如果不做這個控制,底層和上層的左側和上側會重合在一起-->
    <item android:left="3dp"
          android:top="6dp">
        <shape>
            <solid android:color="#b4b5b6"/>
        </shape>
    </item>

    <!--上層的右邊距離底層的右邊3dp, 上層的底部距離底層的底部6dp-->
    <item android:bottom="6dp"
          android:right="3dp">
        <shape>
            <solid android:color="#fff"/>
        </shape>
    </item>
</layer-list>
  • 使用 layer-list 圖
 <TextView
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/shadow"
        android:gravity="center"
        android:text="陰影效果"/> 

3.4 效果4 : 圖片層疊

圖片層疊的時候,有兩種效果,一種是縮放後層疊,一種是不縮放的層疊。預設是縮放效果。具體效果以及實現程式碼如下:

效果圖 1) : 帶有縮放效果的
這裡寫圖片描述
具體程式碼 1):

  • 建立 layer-list
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--預設縮放-->
    <item>
        <bitmap
            android:src="@drawable/ic_launcher"/>
    </item>

    <item android:left="35dp"
          android:top="35dp">
        <bitmap
            android:src="@drawable/ic_launcher"/>
    </item>

    <item android:left="70dp"
          android:top="70dp">
        <bitmap
            android:src="@drawable/ic_launcher"/>
    </item>
</layer-list>

或者也可以使用如下程式碼,實現縮放的疊加圖:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--這種方式拿到的是帶有縮放的效果,即便給item 設定了gravity 並且從模擬器上看到的效果是不縮放的,但是真機上依舊是縮放的效果-->
    <item android:drawable="@drawable/ic_launcher">
    </item>
    <item android:drawable="@drawable/ic_launcher"
          android:left="45dp"
          android:top="45dp">
    </item>
    <item android:drawable="@drawable/ic_launcher"
          android:left="90dp"
          android:top="90dp">
    </item>
</layer-list>
  • 使用 layer-list 圖
  <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/overlay"
    />

效果圖 2):不帶縮放效果的

注意: 
A. 不縮放的時候,必須在 item 節點中使用 bitmap 節點,並給 bitmap 設定 gravity=center ;
B. 雖然在實現縮放效果的時候,可以直接使用 item 中的 drawable屬性,但實現不縮放的效果時,如果還用drawable 屬性,即便給item 設定了gravity =center ,在真機上的效果依舊是縮放的。(但模擬器是不縮放的)

這裡寫圖片描述
具體程式碼 2):

  • 建立 layer-list
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--不縮放-->
    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/ic_launcher"/>
    </item>

    <item android:left="35dp"
          android:top="35dp">
        <bitmap android:gravity="center"
                android:src="@drawable/ic_launcher"/>
    </item>

    <item android:left="70dp"
          android:top="70dp">
        <bitmap android:gravity="center"
                android:src="@drawable/ic_launcher"/>
    </item>

</layer-list>
  • 使用 layer-list 圖
 <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/overlay"
    />

3.5 效果5 :疊加旋轉

效果圖:
這裡寫圖片描述
具體程式碼:

  • 建立 layer-list
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <rotate android:fromDegrees="-10" android:pivotX="0"
                android:pivotY="0">
            <bitmap android:src="@drawable/decibel_blue_background"/>
        </rotate>
    </item>
    <item>
        <rotate android:fromDegrees="10" android:pivotX="0"
                android:pivotY="0">
            <bitmap android:src="@drawable/decibel_orange_background"/>
        </rotate>
    </item>
    <item>
        <rotate android:fromDegrees="30" android:pivotX="0"
                android:pivotY="0">
            <bitmap android:src="@drawable/decibel_red_background"/>
        </rotate>
    </item>


</layer-list>

旋轉的時候,只需要給出 起始的角度( fromdegress )即可。

  • 使用 layer-list 圖
    <!--圖片疊加並帶旋轉效果-->
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/rotate"/>

4. layer-list 的擴充套件使用

4.1.實現選擇器的效果

主要使用元件:RadioGroup Selector layer-list
1). 效果圖:
這裡寫圖片描述

2). 具體程式碼
定義 selector 選擇器
selector 的 item 節點中,直接巢狀 layer-list
當然也可以先寫好layer-list ,然後再去引用

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--被選中時是4dp的底部邊線-->
    <item android:state_checked="true">
        <layer-list>
            <item>
                <shape>
                    <solid android:color="#f00"/>
                </shape>
            </item>
            <item android:bottom="4dp">
                <shape>
                    <solid android:color="#fff"/>
                </shape>
            </item>
        </layer-list>
    </item>

    <!--未被選中的是2dp的底部邊線-->
    <item>
        <layer-list>
            <item>
                <shape>
                    <solid android:color="#f00"/>
                </shape>
            </item>
            <item android:bottom="2dp">
                <shape>
                    <solid android:color="#fff"/>
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

注意:
在上面的程式碼中,由於並沒有具體的shape ,所以可以省略shape , 直接用 color , 簡化後的程式碼如下:

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

    <!--被選中時是4dp的底部邊線-->
    <item android:state_checked="true">
        <layer-list>
            <item>
                <color android:color="#f00"/>
            </item>
            <item android:bottom="5dp">
                <color android:color="#fff"/>
            </item>
        </layer-list>
    </item>

    <!--未被選中的是2dp的底部邊線-->
    <item>
        <layer-list>
            <item>
                <color android:color="#f00"/>
            </item>
            <item android:bottom="2dp">
                <color android:color="#fff"/>
            </item>
        </layer-list>
    </item>
</selector>
  • 使用selector
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:padding="15dp">
    <RadioGroup
        android:id="@+id/rg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <RadioButton
            android:id="@+id/rb1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/selector_bk_rb"
            android:button="@null"
            android:checked="true"
            android:gravity="center"
            android:padding="10dp"
            android:text="第1 個button"/>
        <RadioButton
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/selector_bk_rb"
            android:button="@null"
            android:gravity="center"
            android:padding="10dp"
            android:text="第2 個button"/>
        <RadioButton
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/selector_bk_rb"
            android:button="@null"
            android:gravity="center"
            android:padding="10dp"
            android:text="第3 個button"/>

    </RadioGroup>
</LinearLayout>    

注意:
在 RadioGroup 中,是通過 RadioButton 的 id 來控制是否選中。
所以,如果需要設定某一個 RadioButton 為預設選中,就必須給該 RadioButton 設定 id ;
如果不設定 id ,導致的結果就是該 RadioButton 會一直處於選中狀態!!!