Comment puis-je modifier la couleur d'ondulation lorsque j'utilise? Attr / selectableItemBackground comme arrière-plan?

103

J'ai vu quelques questions SO et ils ont donné quelques méthodes possibles pour réaliser ce que je veux. Par exemple:

  1. Utilisez l' colorControlHighlightattribut dans styles.xml.

    Voici mon styles-v21.xml:

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

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

    Et ça ne marche pas. J'ai également essayé d'ajouter parent="Theme.AppCompatau style "SelectableItemBackground", ou changer en colorControlHighlight(no android: prefix)", ou changer en ?android:attr/selectableItemBackground, ni l'un ni l'autre n'est utile.

  2. Utilisez l' backgroundTintattribut dans la mise en page.

    Alors j'ajoute android:backgroundTint="#5677FC"à mon TextView. Toujours inutile. Ensuite, j'ai essayé de changer android:backgroundTintModepour src_inet src_atop, et ils ne font jamais de différence.

Alors, comment puis-je changer la couleur des ondulations lorsque j'utilise ?attr/selectableItemBackgroundcomme arrière-plan. Je me concentre uniquement sur Lollipop et plus. Merci d'avance!

ywwynm
la source

Réponses:

154

Enfin je trouve la solution: au lieu d'utiliser android:colorControlHighlight directement dans le thème SelectableItemBackground, je devrais écrire un autre style:

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

Ensuite:

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

Enfin ajouter style="@style/SelectableItemBackground" à Viewen layout.xml.

MISE À JOUR 2016/8/26 Après la sortie de N, j'ai constaté que parfois nous ne pouvons pas utiliser cette méthode pour définir la couleur d'ondulation pour une sorte deView (par exemple, le CardView). Maintenant, je recommande vivement aux développeurs d'utiliser RippleDrawable, qui peut également être déclaré en xml. Voici un exemple:

Je veux montrer un effet d'entraînement lorsque l'utilisateur touche / clique sur une CardViewAPI21 ci - dessus, et bien sûr, il devrait y avoir un autre type de retour avant Lollipop. Alors je devrais écrire:

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

et selectable_item_backgrounddans le drawabledossier:

<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_backgrounddans le drawable-v21dossier:

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

enfin, le dossier ripple_blackin drawable(ou 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-->

C'est tout. Pour d'autres vues, vous devriez peut-être utiliser android:background="@drawable/selectable_item_background". N'oubliez pas de définir un OnClickListener, OnTouchListenerou quelque chose comme ceux pour eux, sinon l'ondulation ne s'affichera pas.

ywwynm
la source
14
Utiliser colorControlHighlightau lieu de android:colorControlHighlightfonctionne mieux pour moi, sinon ce n'est que pour la v21 +
Liuting
1
Ce n'est pas la bonne réponse, veuillez consulter la réponse de @ harrane ci-dessous.
Jin
2
Si vous n'avez pas défini de ClickListener, rendez simplement la vue cliquable clickable="true"et l'effet d'entraînement fonctionnera
hedisam
58

Effet d'entraînement sur les appareils pré- et Lollipop +

harrane et Liuting ont raison. La réponse acceptée n'est pas la meilleure façon. Permettez-moi de montrer dans le code comment changer la couleur des ondulations pour les versions pré-Lollipop et supérieures

  1. Votre AppTheme doit hériter de n'importe quel thème AppCompat et contenir l'attribut colorControlHighlight (sans le préfixe «android:»)

    <!-- Application theme. -->
    <style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="colorControlHighlight">#40ffffff</item>
    </style>
  2. Votre vue doit contenir clickable = "true" (ou doit avoir un écouteur de clic défini par programme) et l'arrière-plan doit être "? Attr / selectableItemBackgroundBorderless" ou "? Attr / selectableItemBackground":

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

Remarque: si votre vue parente a un fond blanc, vous ne verrez pas d'effet d'entraînement car elle est blanche. Changer la valeur colorControlHighlight pour une couleur différente

De plus, si vous voulez différentes couleurs d'ondulation sur différentes activités, vous pouvez définir un thème personnel pour chaque activité dans le fichier Manifest, par exemple:

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

Différentes couleurs d'ondulation pour différents fragments dans la même activité?

Vous pouvez modifier les attributs du thème d'activité pour chaque fragment lors de l'exécution. Il suffit de les écraser avant que le fragment ne soit gonflé avec votre style personnalisé et de l'appliquer à un thème actuel:

dans values ​​/ styles.xml

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

Ensuite, dans votre fragment avant l'inflation dans 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;
    }

Ce style ne fonctionnera que pour ce fragment


Différentes couleurs d'ondulation pour différentes vues? (Sucette +)

Vous pouvez changer la couleur d'ondulation pour chaque vue séparément en utilisant l' colorControlHighlightattribut, cela ne fonctionne pas si vous les appliquez directement à une vue:

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

vous devez l'appliquer comme thème:

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

PS En outre, parfois, cette approche aide si vous avez des problèmes inconnus d'ondulation et que vous ne pouvez pas le comprendre. Dans mon cas, j'ai utilisé une bibliothèque coulissante tierce qui a gâché les effets d'entraînement pour toute la mise en page et l'ajout explicite de ce thème à toutes les vues cliquables a fonctionné pour moi.

Kirill Karmazin
la source
10

Il montre un effet d'entraînement avec la couleur sur l'API +21 et un simple fond gris sur la presse pour l'API -21. Ajoutez ce style:

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

Et réglez-le sur la vue:

<Button
   ...
   android:theme="@style/AppTheme.MyRipple" />
Mahdi Khansari
la source
3
Il est important de noter que c'est en effet ce que vous avez écrit android:themeet non ce que les gens utilisent habituellement style.
développeur android
5

Suivez les étapes ci-dessous:

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

-L'attribut style appelle le style que nous avons créé.

L'attribut -Foreground appelle l'attribut sélectionnable par défaut de l'andoride.

styles.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
la source
0

Ce code fonctionne pour moi pour créer une ondulation:

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);
    }
}

Je n'ai trouvé aucun moyen de modifier l'attribut selectableItemBackground. C'est pourquoi je l'ai fait comme ci-dessus.

Mika
la source
0

Dans le thème noir foncé (ou toute autre), essayez d'utiliser comme ci-dessous, créez d'abord ripple_effect.xmldans un drawabledossier et ajoutez du code comme

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

puis définissez l'arrière-plan de votre vue Any comme Linear layout, Button, TextViewetc.

 <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
la source
-1

Utilisez l'attribut de premier plan comme selectableItemBackground et l'attribut d'arrière-plan comme couleur souhaitée.

android:foreground="?attr/selectableItemBackground"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@color/white"
Titto Jose
la source
1
En procédant ainsi, vous n'aurez pas la possibilité de changer la couleur de l'effet d'entraînement. La question -How can I modify ripple color when using ?attr/selectableItemBackground as background?
HB.