Spinner 下拉项目彩色背景的波纹效果 (appcompat-v7 V21)

Ripple effect on Spinner dropdown items colored background (appcompat-v7 V21)

我尝试对 Spinner 下拉项应用波纹效果,如下所示:

activity.java

    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
            this, R.array.array_name, R.layout.simple_spinner_dropdown_item);
    adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);
    Spinner mSpinner = (Spinner) findViewById(R.id.spinner);
    mSpinner.setAdapter(adapter);

simple_spinner_dropdown_item.xml

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@android:id/text1"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="@drawable/spinner_ripple"
   android:ellipsize="marquee"
   android:gravity="center_horizontal"
   android:padding="10dip"
   android:singleLine="true"
   android:textSize="14sp" />

spinner_ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
   <ripple android:color="?android:attr/colorControlHighlight">
       <item><shape>
                  <solid android:color="@android:color/white" />
              </shape>
       </item>
   </ripple>
</item>
</selector>

但在下拉列表中仅适用于第一项并且仅当当前选定的项目不是第一项时 .在所有其他情况下,它会用波纹颜色填充背景项目(因为没有波纹效果)。 我的代码哪里错了?

已尝试:无法在下拉项布局的背景上设置固定颜色并在 Spinner 元素下移动波纹效果,如下所示:

simple_spinner_dropdown_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@android:id/text1"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="@android:color/white"
   android:ellipsize="marquee"
   android:gravity="center_horizontal"
   android:padding="10dip"
   android:singleLine="true"
   android:textSize="14sp" />

activity_layout.xml

<Spinner
   android:id="@+id/spinner"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:drawSelectorOnTop="true"
   android:dropDownSelector="@drawable/spinner_ripple" />

我相信你的 spinner_ripple.xml

需要两层
<!-- Background -->
<ripple android:color="#ff00ff00">
    <item android:drawable="@android:color/black" />
<ripple />

<!-- Ripple color -->
<ripple android:color="#ff00ff00">
    <item android:drawable="@android:color/white" />
<ripple />

如果你想让你的下拉列表项默认为白色,并且只有当用户触摸它们时才用波纹效果突出显示它们,你需要在 spinner_ripple.xml 中实现适当的状态列表 可绘制:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <ripple android:color="?android:attr/colorControlHighlight" />
    </item>
    <item android:state_pressed="false">
        <shape>
            <solid android:color="@android:color/white" />
        </shape>
    </item>
</selector>

此处,android:state_pressed="true"表示选择器项仅在用户实际按下视图时应用。如果您想支持其他选择器状态,请查看 StateListDrawable 参考。

请记住,AppCompat-v7 v21 不支持波纹效果,根据官方 Android Developers blog:

Why are there no ripples on pre-Lollipop? A lot of what allows RippleDrawable to run smoothly is Android 5.0’s new RenderThread. To optimize for performance on previous versions of Android, we've left RippleDrawable out for now.

所以它只适用于 Lollypop。

您的第二种方法是正确的,但如 this question 中所述,android:dropDownSelector 属性不起作用,这是一个众所周知的错误。

另外,如果你想改变下拉背景颜色,你需要设置Spinner's android:popupBackground,而不是设置下拉项的背景。

整个解决方案将是这样的:

popup_background.xml

<!--Based on Android's popup_background_material.xml-->
<!--This changes the background of the drop-down-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    <corners android:radius="2dp" />
    <solid android:color="@android:color/white" />
</shape>

styles.xml

<resources>
    <style name="AppTheme" parent="android:Theme.Material.Light">
        <!--Workaround for the Android bug-->
        <item name="android:dropDownListViewStyle">@style/Theme.MyListView</item>
    </style>

    <style name="Theme.MyListView" parent="@android:style/Widget.Material.ListView.DropDown">
        <item name="android:listSelector">@drawable/spinner_ripple</item>
    </style>
</resources>

activity.xml

...
<Spinner
    android:id="@+id/spinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:dropDownSelector="@drawable/spinner_ripple"
    android:popupBackground="@drawable/popup_background"
    />
...

spinner_ripple.xml(原创)

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <ripple android:color="?android:attr/colorControlHighlight">
            <item>
                <shape>
                    <solid android:color="@android:color/white" />
                </shape>
            </item>
        </ripple>
    </item>
</selector>