web-dev-qa-db-fra.com

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

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

  1. Utilisez l'attribut colorControlHighlight 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.AppCompat au style "SelectableItemBackground", ou de passer à colorControlHighlight(no Android: prefix)", ou de modifier ?android:attr/selectableItemBackground, aucun des deux n'étant utile.

  2. Utilisez l'attribut backgroundTint dans la présentation.

    J'ajoute donc Android:backgroundTint="#5677FC" à ma TextView. Toujours inutile. Ensuite, j'ai essayé de changer Android:backgroundTintMode en src_in et src_atop, et ils ne font jamais une différence.

Alors, comment puis-je changer la couleur d'ondulation lorsque j'utilise ?attr/selectableItemBackground comme arrière-plan. Je me concentre uniquement sur Lollipop et au-dessus. Merci d'avance!

70
ywwynm

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, ajoutez style="@style/SelectableItemBackground" à View dans layout.xml.

MISE À JOUR LE 2016/8/26 Après la publication de N, nous avons constaté que nous ne pouvions parfois pas utiliser cette méthode pour définir la couleur d'ondulation d'une sorte de View (par exemple, CardView). Maintenant, je recommande fortement aux développeurs d’utiliser RippleDrawable, qui peut également être déclaré au format xml. Voici un exemple:

Je veux montrer un effet d'entraînement lorsque l'utilisateur touche/clique sur une CardView au-dessus de API21, et bien sûr, il devrait y avoir un autre type de retour d'information avant Lollipop. Donc 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_background dans le dossier drawable:

<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_background dansdrawable-v21dossier:

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

enfin, le ripple_black dans le dossier 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 OnClickListener, OnTouchListener ou quelque chose de similaire pour eux, sinon l'ondulation ne sera pas affichée.

103
ywwynm

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

harrane et Liuting ont raison. La réponse acceptée n’est pas le meilleur moyen… .. Laissez-moi montrer dans le code comment changer la couleur de l'ondulation pour les versions pré-Lollipop et supérieures

  1. Votre AppTheme doit hériter de tout 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 un programme d'écoute des clics doit être 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 parent a un arrière-plan blanc, vous ne verrez pas d’effet d’entraînement car elle est blanche. Modifier la valeur colorControlHighlight pour une couleur différente

De plus, si vous souhaitez différentes couleurs d’ondulation pour différentes activités, vous pouvez définir un thème personnel pour chaque activité dans le fichier manifeste, 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 au moment de l'exécution. Écrasez-les simplement avant que fragment ne soit gonflé avec votre style personnalisé et appliquez-le à 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


Couleur d'ondulation différente pour différentes vues? (Sucette +)

Vous pouvez modifier la couleur d'ondulation de chaque vue séparément à l'aide de l'attribut colorControlHighlight, il ne fonctionne pas si vous les appliquez directement à une vue:

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

vous devriez l'appliquer en tant que thème:

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

P.S. De plus, cette approche est parfois utile si vous rencontrez des problèmes inconnus avec ondulation et que vous ne pouvez pas le comprendre. Dans mon cas, j’ai utilisé une librairie glissante tierce qui gâchait les effets d’entraînement pour l’ensemble de la mise en page et ajoutait explicitement ce thème à toutes les vues cliquables calculées pour moi.

44
Kirill Karmazin

La réponse acceptée est fausse.

La manière correcte d’utiliser est ce que Liuting a mentionné dans le commentaire . Utilisez colorControlHighlight au lieu de Android:colorControlHighlight pour changer la valeur par défaut colorControlHighlight de AppCompat

* Veuillez consulter http://Android-developers.blogspot.co.uk/2014/10/appcompat-v21-material-design-for-pre.html dans la section Theming *

5
harrane

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.

0
Mika

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 .

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

Et placez-le à la vue:

<Button
   ...
   Android:theme="@style/AppTheme.MyRipple" />
0
Mahdi Khansari

Dans le thème noir foncé (ou n'importe quelle autre application), essayez d'utiliser comme ci-dessous tout d'abord créez ripple_effect.xml dans le dossier drawable et ajoutez le 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 sur votre vue N'importe quel, comme Linear layout, Button, TextView etc.

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

Utilisez l'attribut de premier plan comme selectableItemBackground Et l'attribut d'arrière-plan comme couleur.

Android:foreground="?attr/selectableItemBackground"
    Android:layout_height="wrap_content"
    Android:layout_width="match_parent"
    Android:background="@color/white"
0
Titto Jose