Android中水波紋使用

Anumbrella發表於2017-02-25

我們知道Android5.0比之以前的版本有了很大的改觀。引入了Material Design。引入了一種新的設計理念,關於Material Design不做過多的解釋,如果不理解,可以看看官方文件。好像有牆,你也可以看看中文的文件

在引入了Material Design後,也帶來了一些動畫,而對於View的點選效果-水波紋。是不是特別的酷炫,平時也使用過,但一直沒去總結,今天就來總結一下。好,我們進入主題吧。

對水波紋的使用可以通過兩種方式來實現,第一種就是xml檔案的應用,設定背景為具體的某個xml檔案,當然通過主題背景的設定也可以,我將它歸為第一種方式裡;而第二種就是通過自定義view控制元件來實現,通過第三方的類庫,來實現這種效果。

一、XML方式實現

注意:通過這個設定需要給設定的檢視新增可點選事件,才可以出現效果。因為通過xml實現水波紋是在API-21以上才支援,所以xml檔案需要建立在drawable-v21資料夾下,其他的同理,比如layout則是layout-v21。

1、通過系統自帶的主題,設定xml背景來實現

// 波紋有邊界
android:background="?android:attr/selectableItemBackground"  
// 波紋超出邊界  
android:background="?android:attr/selectableItemBackgroundBorderless"

在xml佈局的檢視中通過背景設定來實現。看看效果:

demo

2、通過自定義xml檔案來設定

在drawable資料夾下新建檔案,然後在background中引用。

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

這個是無界的水波紋。而有界的自定義水波紋,要在節點ripple下建立子節點,然後給節點設定id為@android:id/mask。

<?xml version="1.0" encoding="utf-8"?>
<ripple android:color="@color/colorPrimary" xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/colorAccent"  android:id="@android:id/mask">
    </item>
</ripple>

看看效果:

效果

以上便是簡單的水波紋應用方法。

但有時候我們想給新增水波紋的控制元件新增背景圖片或者自定義水波紋範圍的大小、圖形樣式,我們該怎麼做呢?接著看第三點。

3、通過shape、selector、layer-list標籤自定義xml檔案來設定

①、shape的用法。

shape的子標籤(corners、gradient、padding、size、solid、stroke),我們可以通過設定它的子標籤來設定圖形。

  • corners
<corners    //定義圓角
   android:radius="dimension"      //全部的圓角半徑
   android:topLeftRadius="dimension"   //左上角的圓角半徑
   android:topRightRadius="dimension"  //右上角的圓角半徑
   android:bottomLeftRadius="dimension"    //左下角的圓角半徑
   android:bottomRightRadius="dimension" />    //右下角的圓角半徑
  • gradient
    //gradient用以定義漸變色,可以定義兩色漸變和三色漸變,及漸變樣式
 <gradient
    android:type=["linear" | "radial" | "sweep"]    //共有3中漸變型別,線性漸變(預設)/放射漸變/掃描式漸變
    android:angle="integer"     //漸變角度,必須為45的倍數,0為從左到右,90為從上到下 (僅對線性漸變有效)
    android:centerX="float"     //漸變中心X的相當位置,範圍為0~1
    android:centerY="float"     //漸變中心Y的相當位置,範圍為0~1
    android:startColor="color"   //漸變開始點的顏色
    android:centerColor="color"  //漸變中間點的顏色,在開始與結束點之間
    android:endColor="color"    //漸變結束點的顏色
    android:gradientRadius="float"  //漸變的半徑,只有當漸變型別為radial時才能使用
    android:useLevel=["true" | "false"] />  //使用LevelListDrawable時就要設定為true。設為false時才有漸變效果

android:angle
angle值對應的位置如圖:
angle

android:centerX與android:centerY
centerX、centerY兩個屬性用於設定漸變的中心點位置,僅當漸變型別為放射漸變時有效,型別為分數或小數,不接受Dimension。預設值是0.5,有效值是0.0~1.0,超出該範圍後會看不出漸變效果。centerX、centerY的取值其實是寬和高的百分比;

android:useLevel
useLevel屬性通常不使用。該屬性用於指定是否將該shape當成一個LevelListDrawable來使用,預設值為false。

  • padding
    //padding:用來定義內部邊距

  • size
    //size:是用來定義圖形的大小的。

  • solid
    //solid用以指定內部填充色

<solid  android:color="color" />
  • stroke
    //這是描邊屬性,可以定義描邊的寬度,顏色,虛實線等。
 <stroke
    android:width="dimension"   //描邊的寬度
    android:color="color"   //描邊的顏色             
    // 以下兩個屬性設定虛線
    android:dashWidth="dimension"   //虛線的寬度,值為0時是實線
    android:dashGap="dimension" />      //虛線的間隔

Shape自身的屬性(rectangle、oval、line、ring)

 android:shape=["rectangle" | "oval" | "line" | "ring"]
 shape的形狀,預設為矩形,可以設定為矩形(rectangle)、橢圓形(oval)、線性形狀(line)、環形(ring)
 下面的屬性只有在android:shape="ring時可用:
 android:innerRadius         尺寸,內環的半徑。
 android:innerRadiusRatio    浮點型,以環的寬度比率來表示內環的半徑,
 android:thickness           尺寸,環的厚度
 android:thicknessRatio      浮點型,以環的寬度比率來表示環的厚度,例如,如果android:thicknessRatio="2",
 android:useLevel            boolean值,如果當做是LevelListDrawable使用時值為true,否則為false.

②、selector的用法。

selector就是狀態列表(StateList), 它分為兩種,一種Color-Selector 和Drawable-Selector。

  • Color-Selector
    color-selector 就是顏色狀態列表,可以跟color一樣使用,顏色會隨著元件的狀態而改變。
    檔案的位置儲存於/res/color/filename.xml。
    在Java中使用是:R.color.filename。
    屬性:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="hex_color"               //顏色值,#RGB,$ARGB,#RRGGBB,#AARRGGBB
        android:state_pressed=["true" | "false"]//是否觸控
        android:state_focused=["true" | "false"]//是否獲得焦點
        android:state_selected=["true" | "false"]//是否被狀態
        android:state_checkable=["true" | "false"]//是否可選
        android:state_checked=["true" | "false"]//是否選中
        android:state_enabled=["true" | "false"]//是否可用
        android:state_window_focused=["true" | "false"] />//是否視窗聚焦
</selector>
  • Drawable-Selector
    drawable-selector 是背景圖狀態列表,可以跟圖片一樣使用,背景會根據元件的狀態變化而變化。
    檔案儲存於/res/drawable/filename.xml。
    Java中呼叫:R.drawable.filename。
    屬性:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize=["true" | "false"]//drawable的大小是否當中狀態變化,true表示是變化,false表示不變換,預設為false
    android:dither=["true" | "false"]//當點陣圖與螢幕的畫素配置不一樣時(例如,一個ARGB為8888的點陣圖與RGB為555的螢幕)會自行遞色(dither)。設定為false時不可遞色。預設true
    android:variablePadding=["true" | "false"] >//內邊距是否變化,預設false
    <item
        android:drawable="@[package:]drawable/drawable_resource"//圖片資源
        android:state_pressed=["true" | "false"]//是否觸控
        android:state_focused=["true" | "false"]//是否獲取到焦點
        android:state_hovered=["true" | "false"]//游標是否經過
        android:state_selected=["true" | "false"]//是否選中
        android:state_checkable=["true" | "false"]//是否可勾選
        android:state_checked=["true" | "false"]//是否勾選
        android:state_enabled=["true" | "false"]//是否可用
        android:state_activated=["true" | "false"]//是否啟用
        android:state_window_focused=["true" | "false"] />//所在視窗是否獲取焦點
</selector>

③、layer-list

將多個圖片或上面兩種效果(shape、selector)按照順序層疊起來。

具體的shape、selector、layer-list我就不過多介紹了,網上有很多的教程,這裡只是大概總結了一下用法。

接下來繼續進行我們的水波紋效果介紹,先建立一個shape的xml檔案,儲存在drawable-v21下,命名為custom_shape.xml。如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <corners android:radius="10dp"></corners>
    <solid android:color="@color/colorAccent"></solid>
</shape>

然後再在ripple標籤中引用,如下:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimary">
    <item
        android:id="@android:id/mask"
        android:drawable="@drawable/custom_shape">
    </item>
</ripple>

通過結果發現,這種方式我們先前設定的填充顏色沒有起作用,即

<solid android:color="@color/colorAccent"></solid>

沒有起作用。

我們可以通過下面的方式改變:
去掉android:id=”@android:id/mask”,這行程式碼即可。然後會發現,填充顏色可以使用了。

有了shape的使用,則selector就簡單多了,如下:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimary">
    <item>
        <selector>
            <item
                android:drawable="@mipmap/red_bg"
                android:state_pressed="true"></item>
            <item
                android:drawable="@mipmap/yellow_bg"
                android:state_pressed="false"></item>
        </selector>
    </item>
</ripple>

同理layer-list的使用一樣:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimary">
    <item>
        <layer-list>
            <item>
                <shape>
                    <solid android:color="#FFFFFF" />
                    <corners
                        android:bottomLeftRadius="0.1dp"
                        android:bottomRightRadius="0.1dp"
                        android:topLeftRadius="10dp"
                        android:topRightRadius="10dp" />
                    <stroke
                        android:width="1dp"
                        android:color="#ffa8abad" />
                </shape>
            </item>
            <item
                android:left="1dp"
                android:right="1dp"
                android:top="1dp">
                <shape>
                    <solid android:color="#FFFFFF" />
                    <corners
                        android:bottomLeftRadius="0.1dp"
                        android:bottomRightRadius="0.1dp"
                        android:topLeftRadius="10dp"
                        android:topRightRadius="10dp" />
                    <stroke
                        android:width="1dp"
                        android:color="#ffffffff" />
                </shape>
            </item>
        </layer-list>
    </item>
</ripple>

看看效果:

效果

xml方式實現水波紋終於介紹完了,下面介紹自定義view實現水波紋。。通過這種方式可以相容android5.0以下的系統。好,我們來看看。

二、自定義view控制元件來實現

這裡我簡單介紹一下github上開源的水波紋實現控制元件,控制元件連結
用法比較簡單,把需要實現的檢視包圍在該控制中即可,比如要實現ImageView的點選水波紋效果,如下:

<com.andexert.library.RippleView
  android:id="@+id/more"
  android:layout_width="?android:actionBarSize"
  android:layout_height="?android:actionBarSize"
  android:layout_toLeftOf="@+id/more2"
  android:layout_margin="5dp"
  rv_centered="true">

  <ImageView
    android:layout_width="?android:actionBarSize"
    android:layout_height="?android:actionBarSize"
    android:src="@android:drawable/ic_menu_edit"
    android:layout_centerInParent="true"
    android:padding="10dp"
    android:background="@android:color/holo_blue_dark"/>

</com.andexert.library.RippleView>

監控水波紋的擴散效果,通過新增點選監控實現,如下:

 rippleView.setOnRippleCompleteListener(new RippleView.OnRippleCompleteListener() {

        @Override
        public void onComplete(RippleView rippleView) {
            Log.d("Sample", "Ripple completed");
        }

    });

新增點選事件,如下:

   final RippleView rippleView = (RippleView) findViewById(R.id.rippleView);
    rippleView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //TODO: onRippleViewClick
        }
    });

使用比較簡單,作者的相容性做得也比較好,支援API9+。

Android中水波紋的使用就介紹到這裡,後面我會介紹如何具體實現自定義view來實現具體的水波紋效果。Android中水波紋使用之自定義檢視實現。歡迎,留言!

相關文章