J'utilise la bibliothèque de support Android v21.
J'ai créé un bouton avec une couleur d'arrière-plan personnalisée. Les effets de conception Matériau tels que l’ondulation, la révélation ont disparu (sauf l’altitude au clic) lorsque j’utilise la couleur de fond.
<Button
style="?android:attr/buttonStyleSmall"
Android:background="?attr/colorPrimary"
Android:textColor="@color/white"
Android:textAllCaps="true"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:text="Button1"
/>
Ce qui suit est un bouton normal et les effets fonctionnent très bien.
<Button
style="?android:attr/buttonStyleSmall"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:textAllCaps="true"
Android:text="Button1"
/>
Lorsque vous utilisez Android:background
, vous remplacez une grande partie du style et de l'aspect d'un bouton par une couleur vierge.
Mise à jour: Depuis la version version 23.0.0 de AppCompat , il existe un nouveau style Widget.AppCompat.Button.Colored
qui utilise la variable colorButtonNormal
de votre thème pour la couleur désactivée et colorAccent
pour la couleur activée .
Cela vous permet de l'appliquer à votre bouton directement via
<Button
...
style="@style/Widget.AppCompat.Button.Colored" />
Si vous avez besoin d'une colorButtonNormal
ou colorAccent
personnalisée, vous pouvez utiliser une ThemeOverlay
comme expliqué dans this pro-tip et Android:theme
sur le bouton.
Réponse précédente
Vous pouvez utiliser un dessin dans votre répertoire v21 pour votre arrière-plan, par exemple:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:color="?attr/colorControlHighlight">
<item Android:drawable="?attr/colorPrimary"/>
</ripple>
Cela garantira que votre couleur d'arrière-plan est ?attr/colorPrimary
et que l'animation d'ondulation par défaut utilise le ?attr/colorControlHighlight
par défaut (que vous pouvez également définir dans votre thème si vous le souhaitez).
Remarque: vous devrez créer un sélecteur personnalisé pour une version inférieure à la v21:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:drawable="@color/primaryPressed" Android:state_pressed="true"/>
<item Android:drawable="@color/primaryFocused" Android:state_focused="true"/>
<item Android:drawable="@color/primary"/>
</selector>
En supposant que vous ayez certaines couleurs que vous souhaitez pour l'état par défaut, appuyé et focalisé. Personnellement, j'ai pris une capture d'écran d'une ondulation au milieu de la sélection et extrait l'état primaire/ciblé de celle-ci.
Il existe une autre solution simple consistant à créer un arrière-plan personnalisé pour les boutons "Plats" tout en conservant leurs effets "Matériel".
c'est à dire. :
<FrameLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:background="@color/blue">
<Button
style="?android:attr/buttonStyleSmall"
Android:background="?android:attr/selectableItemBackground"
Android:textColor="@Android:color/white"
Android:textAllCaps="true"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:text="Button1"
/>
</FrameLayout>
Peut être utilisé pour les boutons Plat , cela fonctionne sur l'API> = 11, et vous obtiendrez un effet d'entraînement sur les appareils> = 21, en maintenant les boutons réguliers avant 21 ans jusqu'à ce que AppCompat soit mis à jour pour prendre en charge l'ondulation.
Vous pouvez également utiliser les boutons selectableItemBackgroundBorderless for> = 21 uniquement.
Voici un moyen simple et rétro-compatible de fournir un effet d’ondulation aux boutons en relief avec un arrière-plan personnalisé.
Votre mise en page devrait ressembler à ceci
<Button
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:background="@drawable/my_custom_background"
Android:foreground="?android:attr/selectableItemBackground"/>
J'ai rencontré ce problème aujourd'hui en jouant avec la bibliothèque v22.
En supposant que vous utilisez des styles, vous pouvez définir la propriété colorButtonNormal
et les boutons utiliseront cette couleur par défaut.
<style name="AppTheme" parent="BaseTheme">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/primaryColor</item>
<item name="colorPrimaryDark">@color/primaryColorDark</item>
<item name="colorAccent">@color/accentColor</item>
<item name="colorButtonNormal">@color/primaryColor</item>
</style>
En dehors de cela, vous pouvez toujours créer un style pour le bouton, puis l'utiliser pour chaque bouton si vous aviez besoin d'un assortiment de couleurs (non testé, en spéculant).
N'oubliez pas d'ajouter Android:
devant les noms des éléments dans votre style v21 .
Avec AppCompat (22.1.1+), vous pouvez ajouter un style comme celui-ci:
<style name="MyGreenButton">
<item name="colorButtonNormal">#009900</item>
</style>
Et utilisez-le simplement en appliquant le style:
<Android.support.v7.widget.AppCompatButton
style="@style/MyGreenButton"
Android:layout_width="match_width"
Android:layout_height="wrap_content"
Android:text="A Green Button"
/>
En changeant la couleur par programme, j’ai trouvé que le seul moyen de mettre à jour la couleur (sur les API 15 ou 16) consistait à utiliser la liste des teintes de fond. Et cela ne supprime pas l'animation radiale Nice sur les périphériques API 21:
ColorStateList colorStateList = new ColorStateList(new int[][] {{0}}, new int[] {0xFF009900}); // 0xAARRGGBB
button.setSupportBackgroundTintList(colorStateList);
Dans la mesure où button.setBackground(...)
et button.getBackground().mutate().setColorFilter(...)
ne modifie pas la couleur du bouton sur les API 15 et 16 comme sur l’API 21.
La réponse de @ ianhanniballake est absolument correcte et simple. Mais cela m'a pris quelques jours pour comprendre. Pour quelqu'un qui ne comprend pas sa réponse, voici une implémentation plus détaillée
<Button
Android:id="@+id/btn"
style="@style/MaterialButton"
... />
<style name="MaterialButton" parent="Widget.AppCompat.Button.Colored">
<item name="Android:theme">@style/Theme.MaterialButton</item>
...
</style>
<style name="Theme.MaterialButton" parent="YourTheme">
<item name="colorAccent">@color/yourAccentColor</item>
<item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>
=== Ou ===
<Button
Android:id="@+id/btn"
style="@style/Widget.AppCompat.Button.Colored"
Android:theme="@style/Theme.MaterialButton" />
<style name="Theme.MaterialButton" parent="YourTheme">
<item name="colorAccent">@color/yourAccentColor</item>
<item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>
J'ai utilisé le backgroundTint et le premier plan:
<Button
Android:layout_width="match_parent"
Android:layout_height="40dp"
Android:backgroundTint="@color/colorAccent"
Android:foreground="?android:attr/selectableItemBackground"
Android:textColor="@Android:color/white"
Android:textSize="10sp"/>
Si vous êtes intéressé par ImageButton, vous pouvez essayer cette chose simple:
<ImageButton
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:src="@Android:drawable/ic_button"
Android:background="?attr/selectableItemBackgroundBorderless"
/>
Je suis venu à ce poste à la recherche d’un moyen d’avoir une couleur de fond de mon article ListView
tout en conservant l’ondulation.
J'ai simplement ajouté ma couleur d'arrière-plan et le selectableItemBackground au premier plan:
<style name="my_list_item">
<item name="Android:background">@color/white</item>
<item name="Android:foreground">?attr/selectableItemBackground</item>
<item name="Android:layout_height">@dimen/my_list_item_height</item>
</style>
et cela fonctionne comme un charme. Je suppose que la même technique pourrait également être utilisée pour les boutons. Bonne chance :)
Utilisez backgroundTint
au lieu de background
v22.1
of appcompat-v7
a introduit de nouvelles possibilités. Il est maintenant possible d'assigner un thème spécifique à une seule vue.
Utilisation obsolète de app: theme for styling Toolbar. Vous pouvez maintenant utiliser Android: thème pour les barres d’outils sur tous les appareils de niveau API 7 et supérieur et Android: prise en charge des thèmes pour tous les widgets de l'API de niveau 11 ou supérieur dispositifs.
Au lieu de définir la couleur souhaitée dans un thème global, nous en créons un nouveau et l’attribuons uniquement à la variable Button
.
Exemple:
<style name="MyColorButton" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorButtonNormal">@color/myColor</item>
</style>
Et utilisez ce style comme thème de votre Button
<Button
style="?android:attr/buttonStyleSmall"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:text="Button1"
Android:theme="@style/MyColorButton"/>
Si vous êtes prêt à utiliser une bibliothèque tierce, consultez traex/RippleEffect . Il vous permet d’ajouter un effet Ripple à la vue N&RSQUO;IMPORTE LAQUELLE avec seulement quelques lignes de code. Il vous suffit d’envelopper, dans votre fichier d’agencement XML, l’élément pour lequel vous souhaitez créer un effet d’ondulation avec un conteneur com.andexert.library.RippleView
.
En prime, il nécessite Min SDK 9 afin que vous puissiez avoir une conception cohérente à travers les versions de système d'exploitation.
Voici un exemple tiré du référentiel GitHub des bibliothèques:
<com.andexert.library.RippleView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:rv_centered="true">
<ImageView
Android:layout_width="100dp"
Android:layout_height="100dp"
Android:src="@Android:drawable/ic_menu_edit"
Android:background="@Android:color/holo_blue_dark"/>
</com.andexert.library.RippleView>
Vous pouvez changer la couleur de l'ondulation en ajoutant cet attribut à l'élément RippleView: app:rv_color="@color/my_fancy_ripple_color
<Android.support.v7.widget.AppCompatButton
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:backgroundTint="#fff"
Android:textColor="#000"
Android:text="test"/>
Utilisation
xmlns:app="http://schemas.Android.com/apk/res-auto"
et la couleur acceptera le pré-lolipop
Alex Lockwood décrit deux approches dans l'excellent tutoriel: http://www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html :
Approche n ° 1: Modification de la couleur d’arrière-plan du bouton avec un ThemeOverlay
<!-- res/values/themes.xml -->
<style name="RedButtonLightTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">@color/googred500</item>
</style>
<Button
style="@style/Widget.AppCompat.Button.Colored"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:theme="@style/RedButtonLightTheme"/>
Approche n ° 2: Définition de la teinte de fond de AppCompatButton
<!-- res/color/btn_colored_background_tint.xml -->
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<!-- Disabled state. -->
<item Android:state_enabled="false"
Android:color="?attr/colorButtonNormal"
Android:alpha="?android:attr/disabledAlpha"/>
<!-- Enabled state. -->
<item Android:color="?attr/colorAccent"/>
</selector>
<Android.support.v7.widget.AppCompatButton
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:backgroundTint="@color/btn_colored_background_tint"/>
Appliquer les couleurs par programme:
if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.Lollipop) {
ColorStateList colorStateListRipple = new ColorStateList(
new int[][] {{0}},
new int[] {Color.WHITE} // ripple color
);
RippleDrawable rippleDrawable = (RippleDrawable) myButton.getBackground();
rippleDrawable.setColor(colorStateListRipple);
myButton.setBackground(rippleDrawable); // applying the ripple color
}
ColorStateList colorStateList = new ColorStateList(
new int[][]{
new int[]{Android.R.attr.state_pressed}, // when pressed
new int[]{Android.R.attr.state_enabled}, // normal state color
new int[]{} // normal state color
},
new int[]{
Color.CYAN, // when pressed
Color.RED, // normal state color
Color.RED // normal state color
}
);
ViewCompat.setBackgroundTintList(myButton, colorStateList); // applying the state colors