5

Próbowałem zastosować efekt fali na Spinner przedmiotów rozwijanej tak:odzew na pozycji rozwijanych Spinner kolorowym tle (AppCompat-V7 V21)

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> 

ale na liście rozwijanej działa tylko dla pierwszego elementu i tylko wtedy, gdy wybrano element jest inny niż pierwszy. We wszystkich innych przypadkach wypełnia element tła kolorem (bez efektu marszczenia). Gdzie jest źle mój kod?

już próbował: robi praca ustawić stały kolor na tle układu poz rozwijana i przenieść efekt fali pod elementu Spinner, tak:

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" /> 

Odpowiedz

3

Twoje drugie podejście jest poprawne, ale jak wspomniano w atrybucie this question, android:dropDownSelector atrybut nie działa i jest to dobrze znany błąd.

Ponadto, jeśli chcesz zmienić kolor tła, wybierz ustawienie Spinner'sandroid:popupBackground zamiast ustawiania tła rozwijanego elementu.

Cały roztwór będzie tak:

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 (oryginalna)

<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> 
+0

W ten sposób efekt marszczenia na białym tle jest przenoszony na poziomie motywu: działa, ale działa dla wszystkich spinnerów w mojej aplikacji. Tak więc nie mogę mieć pojedynczego pokrętła z efektem marszczenia na jego własnym tle innym niż ten motyw. – GPack

+0

To niefortunne, ale z powodu błędu Androida jest to jedyny sposób, chyba że chcesz podklasować klasę spinner i spróbować zaimplementować obejście. – stealth

+0

Btw, dlaczego chcesz mieć jeden spinner różni się od innych? – stealth

0

wierzę, potrzebujesz dwóch warstw w 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 /> 
+1

Dwa 'ripple' elementy na tym samym poziomie w xml pod' selector'? Spróbuję, ale myślę, że to nie jest właściwa droga. Dzięki. – GPack

4

Jeśli chcesz mieć swoje pozycje listy rozwijanej być białe domyślnie i podkreślić ich odzew tylko wtedy, gdy użytkownik dotyka je, trzeba wdrożyć właściwego stanu lista w spinner_ripple.xml rozciągliwej:

<?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> 

Tutaj android:state_pressed="true" oznacza, że ​​pozycja selektor stosuje się tylko wtedy, gdy użytkownik naciśnie rzeczywiście widok. Jeśli chcesz obsługiwać inne stany wyborów, sprawdź numer referencyjny StateListDrawable.

Należy pamiętać, że AppCompat-V7 V21 nie obsługuje efekt fali, według oficjalnych Android Developers blog:

Dlaczego nie ma wsady na pre-Lollipop? Wiele z tego, co pozwala na płynne działanie RippleDrawable, to nowy RenderThread z Androidem 5.0. Aby zoptymalizować wydajność w poprzednich wersjach Androida, na razie opuściliśmy RippleDrawable.

Działa to tylko na Lollypop.

+0

W ten sposób po naciśnięciu elementu białe tło zachowuje się i zmienia kolor tła kompozycji na liście rozwijanej. – GPack

+0

Dobrze, sprawdź moją kolejną odpowiedź. To rozwiązuje wszystkie problemy. – stealth

+0

'state_pressed =" false "' atrybut wydaje się nadmiarowy w drugim elemencie. –