Jak mogę zmienić kolor tętnienia, używając? Attr / selectableItemBackground jako tła?

103

Widziałem kilka pytań SO i podali kilka możliwych metod osiągnięcia tego, czego chcę. Na przykład:

  1. Użyj colorControlHighlightatrybutu w styles.xml.

    Oto moje style-v21.xml:

    <style name="SelectableItemBackground">
        <item name="android:colorControlHighlight">#5677FC</item>
        <item name="android:background">?attr/selectableItemBackground</item>
    </style>

    I mój widget:

    <TextView
        android:id="@+id/tv_take_photo_as_bt"
        android:layout_width="280dp"
        android:layout_height="48dp"
        android:text="@string/act_take_photo"
        style="@style/SelectableItemBackground"/>

    I to nie działa. Próbowałem też dodać parent="Theme.AppCompatstyl „SelectableItemBackground”, zmienić colorControlHighlight(no android: prefix)"lub zmienić na ?android:attr/selectableItemBackground, żadne z nich nie jest przydatne.

  2. Użyj backgroundTintatrybutu w układzie.

    Więc dodaję android:backgroundTint="#5677FC"do mojego TextView. Wciąż bezużyteczne. Potem próbowałem zmienić android:backgroundTintModena src_ini src_atop, ale nigdy nie robią różnicy.

Jak więc mogę zmienić kolor tętnienia, gdy używam go ?attr/selectableItemBackgroundjako tła. Skupiam się tylko na Lollipop i nowszych wersjach. Z góry dziękuję!

ywwynm
źródło

Odpowiedzi:

154

Wreszcie znajduję rozwiązanie: zamiast używać android:colorControlHighlightbezpośrednio w motywie SelectableItemBackground, powinienem napisać inny styl:

<style name="SelectableItemTheme">
    <item name="colorControlHighlight">@color/ripple_color</item>
</style>

Następnie:

<style name="SelectableItemBackground">
    <item name="android:theme">@style/SelectableItemTheme</item>
    <item name="android:background">?attr/selectableItemBackground</item>
</style>

Na koniec dodaj style="@style/SelectableItemBackground"do Vieww layout.xml.

ZAKTUALIZOWANO 2016/8/26 Po wydaniu N odkryłem, że czasami nie możemy użyć tej metody, aby ustawić kolor tętnienia dla jakiegoś rodzaju View(na przykład CardView). Teraz bardzo polecam programistom używanie RippleDrawable, które można również zadeklarować w xml. Oto przykład:

Chcę pokazać efekt tętnienia, gdy użytkownik dotknie / kliknie CardViewpowyższy interfejs API21, i oczywiście przed Lollipopem powinien być inny rodzaj informacji zwrotnej. Powinienem więc napisać:

<android.support.v7.widget.CardView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:foreground="@drawable/selectable_item_background"/>

i selectable_item_backgroundw drawablefolderze:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false" android:drawable="@android:color/transparent" />
    <item android:drawable="@color/color_clicked" />
</selector>

selectable_item_backgroundw drawable-v21folderze:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ripple_black" />
</selector>

wreszcie folder ripple_blackin drawable(lub drawable-v21):

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/color_clicked"
    tools:ignore="NewApi" /> <!--you can remove this line if it's in v21 folder-->

Otóż ​​to. W przypadku innych widoków może powinieneś użyć android:background="@drawable/selectable_item_background". Nie zapomnij ustawić OnClickListener, OnTouchListenerlub coś podobnie jak dla nich, inaczej tętnienia nie pokaże.

ywwynm
źródło
14
Użyj colorControlHighlightzamiast android:colorControlHighlightdziała lepiej dla mnie, w przeciwnym razie jest to tylko dla v21 +
Liuting
1
To nie jest właściwa odpowiedź. Zobacz odpowiedź @ harrane poniżej.
Jin
2
W przypadku, gdy nie ustawisz ClickListener, tylko upewnij się widok klikalne clickable="true"i efekt tętnienia zadziała
hedisam
58

Efekt falowania na urządzeniach pre- i Lollipop +

harrane i Liuting mają rację. Przyjęta odpowiedź nie jest najlepszą drogą. Pokażę w kodzie, jak zmienić kolor tętnienia w wersjach wcześniejszych niż Lollipop i wyższych

  1. Twój AppTheme powinien dziedziczyć z dowolnego motywu AppCompat i zawierać atrybut colorControlHighlight (bez prefiksu „android:”)

    <!-- Application theme. -->
    <style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="colorControlHighlight">#40ffffff</item>
    </style>
  2. Twój widok powinien zawierać clickable = "true" (lub powinien mieć programowo ustawiony odbiornik kliknięć), a tło powinno mieć postać „? Attr / selectableItemBackgroundBorderless” lub „? Attr / selectableItemBackground”:

    <LinearLayout
    ...
    android:clickable="true"
    android:background="?attr/selectableItemBackgroundBorderless"/>

Uwaga: jeśli twój widok rodzica ma białe tło, nie zobaczysz efektu tętnienia, ponieważ jest biały. Zmień wartość colorControlHighlight na inny kolor

Ponadto, jeśli chcesz mieć różne kolory tętnienia dla różnych działań, możesz ustawić osobisty motyw dla każdego działania w pliku Manifest, na przykład:

       <activity
        android:name="com.myapp.GalleryActivity"
        android:theme="@style/RedRippleTheme"
        />

Różne kolory tętnień dla różnych fragmentów w tej samej czynności?

Możesz zmienić atrybuty motywu działania dla każdego fragmentu w czasie wykonywania. Po prostu nadpisz je, zanim fragment zostanie napompowany Twoim niestandardowym stylem i zastosuj do bieżącego motywu:

w values ​​/ styles.xml

    <style name="colorControlHighlight_blue">
       <item name="colorControlHighlight">@color/main_blue_alpha26</item>
    </style>

Następnie w Twoim fragmencie przed inflacją w onCreateView():

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       getContext().getTheme().applyStyle(R.style.colorControlHighlight_blue, true); //blue ripple color
       View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
       return view;
    }

Ten styl będzie działał tylko dla tego fragmentu


Inny kolor tętnienia dla różnych widoków? (Lollipop +)

Możesz zmienić kolor tętnienia dla każdego widoku osobno za pomocą colorControlHighlightatrybutu, nie zadziała, jeśli zastosujesz je bezpośrednio do widoku:

    <TextView
     ...
     colorControlHighlight="#40ffffff"/> <!-- DOESN'T WORK -->

powinieneś zastosować go jako motyw:

<TextView
  ...
  android:theme="@style/colorControlHighlight_blue"/>

PS Czasami takie podejście pomaga, jeśli masz nieznane problemy z ripple i nie możesz ich rozgryźć. W moim przypadku użyłem biblioteki przesuwnej innej firmy, która zepsuła efekty ripple dla całego układu i wyraźnie dodałem ten motyw do wszystkich klikalnych widoków, które wypracowały dla mnie.

Kirill Karmazin
źródło
10

Pokazuje efekt tętnienia z kolorem na API +21 i prostym szarym tłem na prasie dla API -21. Dodaj ten styl:

<style name="AppTheme.MyRipple">
   <item name="colorControlHighlight">@color/your_color</item>
   <item name="android:background">?selectableItemBackgroundBorderless</item>
</style>

I ustaw to na widok:

<Button
   ...
   android:theme="@style/AppTheme.MyRipple" />
Mahdi Khansari
źródło
3
Ważne jest, aby zauważyć, że rzeczywiście jest tak, jak napisałeś, android:themea nie to, czego ludzie zwykle używają style.
programista Androida
5

Wykonaj poniższe czynności:

1. Make changes to button view in your layout.xml
2. Add new styles in styles.xml

your_layout.xml

<Button
                        android:id="@+id/setup_submit_button"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="16dp"
                        android:text="@string/action_sign_in"
                        android:textStyle="bold"
                        android:background="@color/colorPrimary"
                        android:textColor="@color/white"
                        style="@style/SelectableItemBackground"
                        android:foreground="?android:attr/selectableItemBackground"/>

- Atrybut style wywołuje styl, który stworzyliśmy.

-Foreground Atrybut wywołuje domyślny wybieralny atrybut andorid.

style.xml

 <style name="SelectableItemTheme">
        <item name="colorControlHighlight">@color/white</item>
    </style>


    <style name="SelectableItemBackground">
        <item name="android:theme">@style/SelectableItemTheme</item>
        <item name="android:background">?attr/selectableItemBackground</item>
    </style>
Prajwal W
źródło
0

Ten kod działa dla mnie, aby utworzyć ripple:

public static void setRippleDrawable(View view, int normalColor, int touchColor) {
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            RippleDrawable rippleDrawable = new RippleDrawable(ColorStateList.valueOf(touchColor), view.getBackground(), null);
            view.setBackground(rippleDrawable);
        } else {
            StateListDrawable stateListDrawable = new StateListDrawable();
            stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(touchColor));
            stateListDrawable.addState(new int[]{android.R.attr.state_focused}, new ColorDrawable(touchColor));
            stateListDrawable.addState(new int[]{}, new ColorDrawable(normalColor));
            view.setBackground(stateListDrawable);
            }
    } catch (Exception e) {
        Log.e(LOG_TAG, "" + e);
    }
}

Nie znalazłem sposobu na zmodyfikowanie atrybutu selectableItemBackground. Dlatego zrobiłem to jak wyżej.

Mika
źródło
0

W ciemnym czarnym motywie (lub dowolnej innej) aplikacji spróbuj użyć jak poniżej, najpierw utwórz ripple_effect.xmlw drawablefolderze i dodaj kod, taki jak

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#f5f5f5">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f5f5f5" />

        </shape>
    </item>

</ripple>

następnie ustaw tło na dowolny widok, np. Linear layout, Button, TextViewitp.

 <TextView
                    android:id="@+id/tvApply"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/ripple_effect"
                    android:clickable="true"
                    android:text="APPLY"
                    android:textColor="#FFFFFF"
                    android:gravity="center"
                    android:textSize="@dimen/_8sdp"
                    android:padding="@dimen/_8sdp"
                    android:focusable="true" />
OmiK
źródło
-1

Użyj atrybutu pierwszego planu jako selectableItemBackground, a atrybutu tła jako żądanego koloru.

android:foreground="?attr/selectableItemBackground"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@color/white"
Titto Jose
źródło
1
Robiąc to w ten sposób, nie będziesz mieć możliwości zmiany koloru efektu tętnienia. Pytanie -How can I modify ripple color when using ?attr/selectableItemBackground as background?
HB.