Bouton Android Standard avec une couleur différente
je voudrais changer légèrement la couleur d'un bouton Android standard afin de mieux correspondre à la marque d'un client.
le meilleur moyen que j'ai trouvé pour le faire jusqu'à présent est de changer le Button
's tirable à la suivante situé dans res/drawable/red_button.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/red_button_pressed" />
<item android:state_focused="true" android:drawable="@drawable/red_button_focus" />
<item android:drawable="@drawable/red_button_rest" />
</selector>
mais faire cela exige que je crée en fait trois tiroirs différents pour chaque bouton que je veux personnaliser (un pour le bouton au repos, un lorsque concentré, et un quand la touche est pressée). Cela semble plus compliqué et non sec.
Tout ce que je veux vraiment faire est d'appliquer une sorte de transformation de couleur sur le bouton. Y a-t-il un moyen plus facile de changer la couleur d'un bouton que ce que je fais?
18 réponses
j'ai découvert que cela peut être fait dans un fichier assez facilement. Mettez quelque chose comme le code suivant dans un fichier nommé custom_button.xml
et puis mettez background="@drawable/custom_button"
dans votre vue de bouton:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="@color/yellow1"
android:endColor="@color/yellow2"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/grey05" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<item android:state_focused="true" >
<shape>
<gradient
android:endColor="@color/orange4"
android:startColor="@color/orange5"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/grey05" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:endColor="@color/blue2"
android:startColor="@color/blue25"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/grey05" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
suite à la réponse de Tomasz, vous pouvez également programmatiquement régler l'ombre du bouton entier en utilisant le mode de multiplication PorterDuff. Cela changera la couleur du bouton plutôt que la teinte.
si vous commencez par un bouton standard en gris:
button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
vous donnera un bouton rouge ombré,
button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);
vous donnera un bouton vert ombré, etc., dans lequel la première valeur est la couleur en hexadécimal format.
il fonctionne en multipliant la valeur de couleur du bouton courant par votre valeur de couleur. Je suis sûr qu'il y est aussi beaucoup plus que vous pouvez faire avec ces modes.
Mike, vous pourriez être intéressé par les filtres couleur.
un exemple:
button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));
essayez ceci pour obtenir la couleur que vous voulez.
C'est ma solution qui fonctionne parfaitement à partir de de L'API 15 . Cette solution conserve tous les effets de clic de bouton par défaut, comme le matériel RippleEffect
. Je ne l'ai pas testé sur les APIs inférieurs, mais ça devrait marcher.
Tout ce que vous devez faire, est:
1) Créer un style qui change seulement colorAccent
:
<style name="Facebook.Button" parent="ThemeOverlay.AppCompat">
<item name="colorAccent">@color/com_facebook_blue</item>
</style>
je recommande d'utiliser
ThemeOverlay.AppCompat
ou votre principalAppTheme
comme parent, pour garder le reste de vos styles.
2) ajoutez ces deux lignes à votre button
widget:
style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Facebook.Button"
parfois, votre nouveau
colorAccent
n'apparaît pas dans Android Studio Preview, mais lorsque vous lancez votre application sur le téléphone, la couleur sera changé.
Exemple de widget Bouton
<Button
android:id="@+id/sign_in_with_facebook"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/sign_in_facebook"
android:textColor="@android:color/white"
android:theme="@style/Facebook.Button" />
vous pouvez maintenant aussi utiliser l'attribut backgroundTint
D'appcompat-v7 AppCompatButton avec l'attribut backgroundTint
:
<android.support.v7.widget.AppCompatButton
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:backgroundTint="#ffaa00"/>
j'aime la suggestion du filtre couleur dans les réponses précédentes de @conjugatedirection et @Tomasz; cependant, j'ai trouvé que le code fourni jusqu'à présent n'était pas aussi facilement appliqué que je m'y attendais.
tout d'abord, il n'a pas été mentionné où à appliquer et nettoyer le filtre couleur. Il est possible qu'il y ait d'autres bons endroits pour le faire, mais ce qui m'est venu à l'esprit était un Ontouchtener .
D'après ma lecture de la question initiale, la solution idéale serait celle qui n'implique aucune image. La réponse acceptée en utilisant custom_button.xml de @emmby est probablement un meilleur ajustement que les filtres couleur si c'est votre but. Dans mon cas, je commence avec une image png d'un concepteur D'UI de ce que le bouton est censé ressembler. Si je mets le bouton background sur cette image, le retour de surlignage par défaut est complètement perdu. Ce code remplace ce comportement par un effet d'obscurcissement programmatique.
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 0x6D6D6D sets how much to darken - tweak as desired
setColorFilter(v, 0x6D6D6D);
break;
// remove the filter when moving off the button
// the same way a selector implementation would
case MotionEvent.ACTION_MOVE:
Rect r = new Rect();
v.getLocalVisibleRect(r);
if (!r.contains((int) event.getX(), (int) event.getY())) {
setColorFilter(v, null);
}
break;
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
setColorFilter(v, null);
break;
}
return false;
}
private void setColorFilter(View v, Integer filter) {
if (filter == null) v.getBackground().clearColorFilter();
else {
// To lighten instead of darken, try this:
// LightingColorFilter lighten = new LightingColorFilter(0xFFFFFF, filter);
LightingColorFilter darken = new LightingColorFilter(filter, 0x000000);
v.getBackground().setColorFilter(darken);
}
// required on Android 2.3.7 for filter change to take effect (but not on 4.0.4)
v.getBackground().invalidateSelf();
}
});
j'ai extrait ceci comme une classe séparée pour l'application à plusieurs boutons - montré comme classe interne anonyme juste pour obtenir l'idée.
si vous faites des boutons de couleur avec XML, vous pouvez rendre le code un peu plus propre en spécifiant l'état focalisé et pressé dans un fichier séparé et les réutiliser. Mon bouton vert ressemble à ceci:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/button_focused"/>
<item android:state_pressed="true" android:drawable="@drawable/button_pressed"/>
<item>
<shape>
<gradient android:startColor="#ff00ff00" android:endColor="#bb00ff00" android:angle="270" />
<stroke android:width="1dp" android:color="#bb00ff00" />
<corners android:radius="3dp" />
<padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
</shape>
</item>
</selector>
la solution la plus courte qui fonctionne avec N'importe quelle version Android:
<Button
app:backgroundTint="@color/my_color"
Notes / Exigences :
- utilisez l'espace de noms
app:
et pas L'espace de nomsandroid:
! -
appcompat version > 24.2.0
dépendances { compiler 'com.Android.support: appcompat-v7: 25.3.1" }
j'utilise cette approche
de style.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:colorPrimaryDark">#413152</item>
<item name="android:colorPrimary">#534364</item>
<item name="android:colorAccent">#534364</item>
<item name="android:buttonStyle">@style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="android:colorButtonNormal">#534364</item>
<item name="android:textColor">#ffffff</item>
</style>
comme vous pouvez le voir ci-dessus, j'utilise un style personnalisé pour mon bouton. La couleur du bouton correspond à la couleur de l'accent. Je trouve que c'est une bien meilleure approche que de définir android:background
que je ne perdrai pas l'effet d'ondulation fournit Google.
il y a une voie beaucoup plus facile maintenant: android-holo-colors.com
il vous permettra de changer les couleurs de tous les Holo drawables (boutons, spinners, ...) facilement. Vous sélectionnez la couleur et téléchargez ensuite un fichier zip contenant des tirables pour toutes les résolutions.
utilisez - le de cette façon:
buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);
dans <Button>
utiliser android:background="#33b5e5"
. ou mieux android:background="@color/navig_button"
le DroidUX la bibliothèque de composants a un ColorButton
widget dont la couleur peut être changée facilement, à la fois via la définition xml et programmatiquement au moment de l'exécution, de sorte que vous pouvez même laisser l'utilisateur pour régler la couleur du bouton/Thème si votre application le permet.
vous pouvez également utiliser cet outil en ligne pour personnaliser votre bouton http://angrytools.com/android/button / et utilisez android:background="@drawable/custom_btn"
pour définir le bouton personnalisé dans votre mise en page.
vous pouvez définir le thème de votre bouton à ce
<style name="AppTheme.ButtonBlue" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@color/HEXColor</item>
<item name="android:textColor">@color/HEXColor</item>
</style>
un moyen facile est de définir juste une classe de bouton personnalisé qui accepte toutes les propriétés que vous désirez comme le rayon, le gradient, la couleur pressée, la couleur normale, etc. et puis utilisez simplement cela dans vos mises en page XML au lieu de configurer L'arrière-plan en utilisant XML. Un échantillon est ici
C'est extrêmement utile si vous avez beaucoup de boutons avec les mêmes propriétés de rayon, choisis la couleur etc. Vous pouvez personnaliser votre bouton hérité pour gérer ces propriétés supplémentaires.
résultat (Aucun sélecteur D'arrière-plan n'a été utilisé).
Bouton Normal
Bouton Pressé
la façon dont je fais un bouton stylé différent qui fonctionne assez bien est de sous-classer l'objet du bouton et d'appliquer un filtre couleur. Cela permet également de gérer les États activés et désactivés en appliquant un alpha au bouton.
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.Button;
public class DimmableButton extends Button {
public DimmableButton(Context context) {
super(context);
}
public DimmableButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DimmableButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@SuppressWarnings("deprecation")
@Override
public void setBackgroundDrawable(Drawable d) {
// Replace the original background drawable (e.g. image) with a LayerDrawable that
// contains the original drawable.
DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
super.setBackgroundDrawable(layer);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void setBackground(Drawable d) {
// Replace the original background drawable (e.g. image) with a LayerDrawable that
// contains the original drawable.
DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
super.setBackground(layer);
}
/**
* The stateful LayerDrawable used by this button.
*/
protected class DimmableButtonBackgroundDrawable extends LayerDrawable {
// The color filter to apply when the button is pressed
protected ColorFilter _pressedFilter = new LightingColorFilter(Color.LTGRAY, 1);
// Alpha value when the button is disabled
protected int _disabledAlpha = 100;
// Alpha value when the button is enabled
protected int _fullAlpha = 255;
public DimmableButtonBackgroundDrawable(Drawable d) {
super(new Drawable[] { d });
}
@Override
protected boolean onStateChange(int[] states) {
boolean enabled = false;
boolean pressed = false;
for (int state : states) {
if (state == android.R.attr.state_enabled)
enabled = true;
else if (state == android.R.attr.state_pressed)
pressed = true;
}
mutate();
if (enabled && pressed) {
setColorFilter(_pressedFilter);
} else if (!enabled) {
setColorFilter(null);
setAlpha(_disabledAlpha);
} else {
setColorFilter(null);
setAlpha(_fullAlpha);
}
invalidateSelf();
return super.onStateChange(states);
}
@Override
public boolean isStateful() {
return true;
}
}
}
les valeurs de\styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="RedAccentButton" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">#ff0000</item>
</style>
puis:
<Button
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="text" />
<Button
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:text="text" />
<Button
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="text"
android:theme="@style/RedAccentButton" />
<Button
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:text="text"
android:theme="@style/RedAccentButton" />