Android控制元件點選圓形陰影反饋解決方案

liuly0218發表於2018-01-19

Android控制元件點選圓形陰影反饋解決方案

願景

對於手機App而言,沒有反饋效果的按鈕使用體驗是不舒服的。最近在深入學習Material Design,對其中的ripple效果比較感興趣。我想著嘗試給可點選的圖形按鈕一個簡單的觸控動態反饋效果,這樣不至於太生硬。

想實現的效果如下:

Android控制元件點選圓形陰影反饋解決方案
動態圖片如下:

Android控制元件點選圓形陰影反饋解決方案

實現

經過查詢相關資料和自己實踐,發現了一個簡單的方式,連結如下:

https://yq.aliyun.com/articles/12407

波紋效果(Ripple):

當你使用了Material主題後,波紋動畫會自動應用在所有的控制元件上,我們當然可以來設定其屬性來調整到我們需要的效果。 可以通過如下程式碼設定波紋的背景:

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

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

使用效果如下:

B1是不設任何背景的按鈕

B2設定了?android:attr/selectableItemBackground

B3設定了?android:attr/selectableItemBackgroundBorderless

詳情可以點選上面的連結看看。

問題

我個人覺得這樣的反饋效果還是比較OK的,可是試驗之後發現了這個屬性在5.0以上系統執行一切正常,但在5.0以下系統執行是會導致程式崩潰的,對的,即使在佈局的xml中對控制元件新增tools:targetApi="LOLLIPOP",在4.1系統的模擬器中執行也還是會崩潰的!!!真機沒有測試。

<ImageView
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:background="?android:selectableItemBackgroundBorderless"
    android:clickable="true"
    android:src="@mipmap/ic_launcher_round"
    tools:targetApi="LOLLIPOP" />
複製程式碼

錯誤如下:

android.view.InflateException: Binary XML file line #0: Error inflating class ImageView

應該是5.0以下系統的主題中沒有這個屬性,導致xml解析出錯。

為解決這個問題,我想著在程式碼中動態新增該屬性,可以解決這個問題,只不過在5.0以下系統會沒有觸控反饋(反正現在大部分Android手機都是5.0以上系統的)。

解決

解決方案如下:

activity_main.xml程式碼如下:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    android:elevation="4dp"
    tools:targetApi="LOLLIPOP">

    <ImageView
        android:id="@+id/iv_menu"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:padding="2dp"
        android:src="@drawable/ic_menu" />

    <ImageView
        android:id="@+id/iv_split_screen"
        android:layout_width="28dp"
        android:layout_height="28dp"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="70dp"
        android:padding="2dp"
        android:src="@drawable/ic_split_screen" />

    <ImageView
        android:id="@+id/iv_settings"
        android:layout_width="26dp"
        android:layout_height="26dp"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="16dp"
        android:src="@drawable/ic_settings" />


</RelativeLayout>
複製程式碼

MainActivity.java程式碼如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private ImageView iv_menu;
private ImageView iv_split_screen;
private ImageView iv_settings;

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

private void initView() {
    iv_menu = (ImageView) findViewById(R.id.iv_menu);
    iv_split_screen = (ImageView) findViewById(R.id.iv_split_screen);
    iv_settings = (ImageView) findViewById(R.id.iv_settings);

    if (Build.VERSION.SDK_INT >= 21) {//5.0以上系統判斷
        int[] attrs = {android.R.attr.selectableItemBackgroundBorderless};
        TypedArray typedArray = getTheme().obtainStyledAttributes(attrs);
        int resourceId = typedArray.getResourceId(0, 0);
        iv_menu.setBackgroundResource(resourceId);
        iv_split_screen.setBackgroundResource(resourceId);
        iv_settings.setBackgroundResource(resourceId);
    }

    iv_menu.setOnClickListener(this);
    iv_split_screen.setOnClickListener(this);
    iv_settings.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.iv_menu:
            ToastUtils.showToast("點選了選單");
            break;
        case R.id.iv_split_screen:
            ToastUtils.showToast("點選了分屏");
            break;
        case R.id.iv_settings:
            ToastUtils.showToast("點選了設定");
            break;
    }
}
複製程式碼

}

總結

開發中遇到的問題,在此記錄一下,關鍵程式碼如下:

    if (Build.VERSION.SDK_INT >= 21) {//5.0以上系統判斷
        int[] attrs = {android.R.attr.selectableItemBackgroundBorderless};
        TypedArray typedArray = getTheme().obtainStyledAttributes(attrs);
        int resourceId = typedArray.getResourceId(0, 0);
        iv_menu.setBackgroundResource(resourceId);
        iv_split_screen.setBackgroundResource(resourceId);
        iv_settings.setBackgroundResource(resourceId);
    }

    iv_menu.setOnClickListener(this);
    iv_split_screen.setOnClickListener(this);
    iv_settings.setOnClickListener(this);
複製程式碼

相關文章