5

I can't seem to get the pressed state ripple to work on a Spinner. The individual drop down items have the ripple, but not the spinner itself. I thought maybe this was expected behavior, but this animation from the material design guidelines clearly shows the spinner with a pressed state ripple before the options drop dropdown appears.

https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0B3321sZLoP_HTS1LdnhrTl9TRzg/components-buttons-otherbuttons-060203_MobileDropdowns_xhdpi_006.webm

Darren Hinderer
  • 418
  • 1
  • 6
  • 12
  • Can you post what you tried until now? Maybe this can help http://stackoverflow.com/questions/27860815/ripple-effect-on-spinner-dropdown-items-colored-background-appcompat-v7-v21 – bonnyz Nov 02 '15 at 21:17

6 Answers6

2

I created a new Spinner in an Activity and as you described, the RippleDrawable is not applied to the Spinner using the v7 compatibility library or on Android 5.0+. This isn't surprising to me; Google often fails to implement its own design.

To have the affect, all I did was create a RippleDrawable in res/values-v21/ and set that to be the background on the Spinner using spinner.setBackgroundResource(R.drawable.spinner_background);. I'm sure you can also set this in your theme.

Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
  • I'm starting to think Google purposely didn't implement it's own design because the popup/dropdown comes up so quickly. It's still very frustrating to me, but maybe I'm the only person this is really bothering. Setting the background to this removes the existing background which has a pressed state and tinted indicator. It also is not backwards compatible. – Darren Hinderer Nov 09 '15 at 23:47
0

set these Spinner properties in xml

android:background="@drawable/ripple_effect"
android:dropDownSelector="@drawable/ripple_effect"

and ripple_effect.xml will look like this

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

    <item android:id="@android:id/mask">
        <shape android:shape="rectangle" >
           <solid android:color="?android:colorAccent" />
        </shape>
    </item>
</ripple>
  • Setting the background to this removes the existing background which has a pressed state and tinted indicator. It also is not backwards compatible. – Darren Hinderer Nov 09 '15 at 23:42
0

There is a library on Github, i.e. Material Ripple Layout. This library supports pre-Lollipop and Lollipop devices. Also, so you can create your own color for the ripple. Here's the usage:

Spinner spinner = (Spinner) findViewById(R.id.spinner);
MaterialRippleLayout.on(spinner)
       .rippleColor(Color.BLACK)
       .create();

But I don't use that library. I'm using the Spinner's default ripple which is introduced in Support Library rev 23.0.1, by compiling: compile 'com.android.support:appcompat-v7:23.0.1' in build.gradle of the app module.

So, here's my complete code for the Spinner layout:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:dropDownVerticalOffset="@dimen/dropDown_spinner"
        style="@style/SpinnerStyle"/> <!-- apply the ripple style -->

</RelativeLayout>

The style is defined in res/values/styles.xml:

<style name="SpinnerStyle" parent="Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
    <item name="android:background">?android:selectableItemBackground</item>
    <item name="android:dropDownSelector">?android:selectableItemBackground</item>
    <item name="android:divider">@null</item>
    <item name="overlapAnchor">true</item>
</style>

After that, the ripple effect should work as expected.

Anggrayudi H
  • 14,977
  • 11
  • 54
  • 87
0

I've been using this cool library to apply ripple effects to some views. I like it, because you can wrap any view in the XML file and it will apply the ripple effect.

https://github.com/balysv/material-ripple

Hope it helps.

Joao Dias
  • 83
  • 10
0

Hope below code will give some sense to Ripple effect on Spinner.

ripple_spinner.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>

Your XML :-

your_acitivity.xml

<Spinner
    android:id="@+id/spinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:dropDownSelector="@drawable/ripple_spinner"
    android:popupBackground="@drawable/popup_spinner_item_background"
    />

Below will change the background of the drop-down.

popup_spinner_item_background.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    <corners android:radius="2dp" />
    <solid android:color="@android:color/white" />
</shape>

In your res/values/styles.xml :-

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>

Hope it will help you.

KishuDroid
  • 5,411
  • 4
  • 30
  • 47
0

There is no ripple for the Spinner, as the background is not ripplable. I make it as following in a selectableItemBackgroundBorderless layout (https://developer.android.com/training/material/animations.html#Touch):

  1. a 0-width Spinner, and remove the arrow down background (use @null will be ok), even i remove the background of a normal Spinner, it has no ripper, so i use TextView and ImageView like google calendar.

  2. a TextView + ImageView (for the arrow down)

When user clicks the TextView/ImageView, it has ripple animations, then call Spinner.performClick. And I want it as the normal dropdown, so i make a 0-width spinner, as the gone Spinner won't call onItemSelected.

for the hidden adapter, it may like this:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = super.getView(position, convertView, parent);
    ((TextView) view).setText("");
    return view;
}

The layout click listener:

layout.setOnClickListener(() -> {
    spinner.performClick();
});

For spinner item listener:

spinner.setOnItemSelectedListener(() -> {
    // this requires spinner's visiblity is not gone
});
liudongmiao
  • 455
  • 4
  • 7