¿Cómo puedo modificar el color de la ondulación cuando uso? Attr / selectableItemBackground como fondo?

103

He visto algunas preguntas SO y me dieron algunos métodos posibles para lograr lo que quiero. Por ejemplo:

  1. Utilice el colorControlHighlightatributo en styles.xml.

    Aquí está mi styles-v21.xml:

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

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

    Y no funciona. También intenté agregar parent="Theme.AppCompatal estilo "SelectableItemBackground", o cambiar a colorControlHighlight(no android: prefix)", o cambiar a ?android:attr/selectableItemBackground, ninguno es útil.

  2. Utilice backgroundTintatributo en el diseño.

    Así que agrego android:backgroundTint="#5677FC"a mi TextView. Todavía inútil. Luego traté de cambiar android:backgroundTintModea src_iny src_atop, y nunca hicieron la diferencia.

Entonces, ¿cómo puedo cambiar el color de la ondulación cuando lo uso ?attr/selectableItemBackgroundcomo fondo? Solo me concentro en Lollipop y más. ¡Gracias de antemano!

ywwynm
fuente

Respuestas:

154

Finalmente encuentro la solución: en lugar de usarlo android:colorControlHighlightdirectamente en el tema SelectableItemBackground, debería escribir otro estilo:

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

Luego:

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

Por último añadir style="@style/SelectableItemBackground"que Viewen layout.xml.

ACTUALIZADO EL 26/8/2016 Después del lanzamiento de N, descubrí que a veces no podemos usar este método para establecer el color de rizado para algún tipo de View(por ejemplo, el CardView). Ahora recomiendo encarecidamente a los desarrolladores que utilicen RippleDrawable, que también se puede declarar en xml. Aquí hay un ejemplo:

Quiero mostrar un efecto CardViewdominó cuando el usuario toca / hace clic en una API21 anterior y, por supuesto, debería haber otro tipo de comentarios antes de Lollipop. Entonces debería escribir:

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

y selectable_item_backgrounden drawablecarpeta:

<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_backgrounden drawable-v21carpeta:

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

finalmente, la carpeta ripple_blackin drawable(o 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-->

Eso es. Para otras vistas, tal vez debería usar android:background="@drawable/selectable_item_background". No olvide establecer una OnClickListener, OnTouchListenero algo similar para ellos, de lo contrario, la ondulación no se mostrará.

ywwynm
fuente
14
Usar en colorControlHighlightlugar de android:colorControlHighlightfunciona mejor para mí, de lo contrario, es solo para v21 +
Liuting
1
Esta no es la respuesta correcta, consulte la respuesta de @ harrane a continuación.
Jin
2
En caso de que no haya configurado un ClickListener, simplemente haga que se pueda hacer clic en la vista clickable="true"y el efecto
dominó
58

Efecto dominó en dispositivos pre y Lollipop +

Harrane y Liuting tienen razón. La respuesta aceptada no es la mejor forma. Permítame mostrarle en el código cómo cambiar el color de la ondulación para las versiones anteriores a Lollipop y superiores

  1. Su AppTheme debe heredar de cualquier tema de AppCompat y contener el atributo colorControlHighlight (sin el prefijo 'android:')

    <!-- Application theme. -->
    <style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="colorControlHighlight">#40ffffff</item>
    </style>
    
  2. Su vista debe contener clickable = "true" (o debe tener un detector de clics configurado de manera programática) y el fondo debe ser "? Attr / selectableItemBackgroundBorderless" o "? Attr / selectableItemBackground":

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

Nota: si su vista principal tiene un fondo blanco, no verá el efecto dominó ya que es blanco. Cambiar el valor de colorControlHighlight para un color diferente

Además, si desea diferentes colores de ondulación en diferentes actividades, puede establecer un tema personal para cada actividad en el archivo de manifiesto, por ejemplo:

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

¿Diferentes colores de ondulación para diferentes fragmentos en la misma actividad?

Puede cambiar los atributos del tema de actividad para cada fragmento en tiempo de ejecución. Simplemente sobrescríbalos antes de que el fragmento se infle con su estilo personalizado y aplíquelo a un tema actual:

en valores / estilos.xml

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

Luego, en su fragmento antes de la inflación en 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;
    }

Este estilo funcionará solo para este fragmento


¿Diferentes colores de ondulación para diferentes vistas? (Piruleta +)

Puede cambiar el color de la ondulación para cada vista por separado usando el colorControlHighlightatributo, no funciona si los aplica a una vista directamente:

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

deberías aplicarlo como tema:

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

PD: Además, a veces este enfoque ayuda si tiene problemas desconocidos con la ondulación y no puede resolverlos. En mi caso, utilicé una biblioteca deslizante de terceros que estropeó los efectos de onda para todo el diseño y agregué explícitamente este tema a todas las vistas en las que se puede hacer clic.

Kirill Karmazin
fuente
10

Muestra un efecto dominó con color en API +21 y un fondo gris simple en la prensa para API -21. Agrega este estilo:

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

Y configúrelo en la vista:

<Button
   ...
   android:theme="@style/AppTheme.MyRipple" />
Mahdi Khansari
fuente
3
Es importante darse cuenta de que, de hecho, es lo que escribió android:themey no lo que la gente suele usar style.
desarrollador de Android
5

Siga los pasos siguientes:

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

-El atributo de estilo llama al estilo que creamos.

-El atributo de primer plano llama al atributo seleccionable predeterminado de andorid.

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

Este código me funciona para crear una onda:

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

No encontré ninguna forma de modificar el atributo selectableItemBackground. Por eso lo hice como arriba.

Mika
fuente
0

En la aplicación de tema negro oscuro (o cualquier otra), intente usarla como se muestra a continuación, primero cree ripple_effect.xmlen la drawablecarpeta y agregue código como

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

luego configure el fondo en su vista Cualquiera, como 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
fuente
-1

Utilice el atributo de primer plano como selectableItemBackground y el atributo de fondo como el color que desee.

android:foreground="?attr/selectableItemBackground"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@color/white"
Titto José
fuente
1
Al hacerlo así, no tendrá la opción de cambiar el color del efecto dominó. La pregunta -How can I modify ripple color when using ?attr/selectableItemBackground as background?
HB.