Стандартная кнопка Android с другим цветом

Я хочу немного изменить цвет стандартной кнопки Android, чтобы лучше соответствовать брендингу клиента.

Лучший способ, который я нашел для этого, - изменить Button на следующий drawable, расположенный в 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>

Но для этого требуется, чтобы я на самом деле создавал три разных чертежа для каждой кнопки, которую я хочу настроить (один для кнопки в состоянии покоя, один при фокусировке и один при нажатии). Это кажется более сложным и не сухим, чем мне нужно.

Все, что я действительно хочу сделать, это применить к кнопке какое-то цветовое преобразование. Есть ли более простой способ изменить цвет кнопки, чем я делаю?

Ответы

Ответ 1

Я обнаружил, что все это можно сделать в одном файле довольно легко. Поместите что-то вроде следующего кода в файл с именем custom_button.xml, а затем установите background="@drawable/custom_button" в окне просмотра кнопок:

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

Ответ 2

Следуя ответу Томаша, вы также можете программно установить оттенок всей кнопки, используя режим умножения PorterDuff. Это изменит цвет кнопки, а не только оттенок.

Если вы начинаете со стандартной серой затененной кнопки:

button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);

даст вам красную затененную кнопку,

button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);

даст вам зеленую затененную кнопку и т.д., где первым значением является цвет в шестнадцатеричном формате.

Он работает, умножая текущее значение цвета кнопки на ваше значение цвета. Я уверен, что с этими режимами вы также можете многое сделать.

Ответ 3

Майк, вас могут заинтересовать цветовые фильтры.

Пример:

button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));

попробуйте сделать это, чтобы достичь желаемого цвета.

Ответ 4

Это мое решение, которое отлично работает с от API 15. Это решение сохраняет все эффекты нажатия кнопки по умолчанию, например материал RippleEffect. Я не тестировал его на более низких API, но он должен работать.

Все, что вам нужно сделать, это:

1) Создайте стиль, который изменяется только colorAccent:

<style name="Facebook.Button" parent="ThemeOverlay.AppCompat">
    <item name="colorAccent">@color/com_facebook_blue</item>
</style>

Я рекомендую использовать ThemeOverlay.AppCompat или ваш основной AppTheme как родительский, чтобы сохранить остальные стили.

2) Добавьте эти две строки в виджет button:

style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Facebook.Button"

Иногда ваш новый colorAccent не отображается в Android Studio Preview, но при запуске приложения на телефоне цвет будет изменен.


Виджет кнопки образца

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

Кнопка выбора с пользовательским цветом

Ответ 5

Теперь вы можете также использовать appcompat-v7 AppCompatButton с атрибутом 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"/>

Ответ 6

Мне нравится предложение цветового фильтра в предыдущих ответах @conjugatedirection и @Tomasz; Тем не менее, я обнаружил, что код, представленный до сих пор, был не так легко применен, как я ожидал.

Во-первых, не было указано , где применить и очистить цветной фильтр. Возможно, есть и другие хорошие места для этого, но то, что мне показалось, было OnTouchListener.

Из моего чтения исходного вопроса идеальным решением было бы то, что не связано с изображениями. Принятый ответ с использованием custom_button.xml из @emmby, вероятно, лучше подходит, чем цветовые фильтры, если ваша цель. В моем случае я начинаю с изображения png от дизайнера пользовательского интерфейса, из которого должна выглядеть кнопка. Если я установил фон кнопки для этого изображения, то по умолчанию обратная связь будет полностью потеряна. Этот код заменяет это поведение программным эффектом затемнения.

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

Я извлек это как отдельный класс для приложения на несколько кнопок - показан как анонимный внутренний класс, чтобы получить эту идею.

Ответ 7

Если вы создаете цветные кнопки с XML, вы можете сделать код немного более чистым, указав сфокусированное и нажатое состояние в отдельном файле и повторно используя их. Моя зеленая кнопка выглядит так:

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

Ответ 8

Самое короткое решение, которое работает с любой версией Android:

<Button
     app:backgroundTint="@color/my_color"

Примечания/Требования:

  • Используйте пространство имен app: и не пространство имен android:!
  • appcompat version > 24.2.0

    зависимости {   msgstr " }

Объяснение: введите описание изображения здесь

Ответ 9

Я использую этот подход

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>

Как вы можете видеть выше, я использую собственный стиль для своей кнопки. Цвет кнопки соответствует цвету акцента. Я считаю, что это гораздо лучший подход, чем установка android:background, поскольку я не потеряю эффект пульсации, который предоставляет Google.

Ответ 10

Теперь намного проще: android-holo-colors.com

Это позволит вам легко менять цвета всех головоломок (кнопок, прядильников,...). Вы выбираете цвет, а затем загружаете zip файл, содержащий чертежи для всех разрешений.

Ответ 11

Используйте его следующим образом:

buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);

Ответ 12

В <Button> используйте android:background="#33b5e5". или лучше android:background="@color/navig_button"

Ответ 13

В библиотеке компонентов DroidUX есть ColorButton, чей цвет можно легко изменить, как с помощью определения xml, так и программно во время выполнения, поэтому вы можете даже позволить пользователю установить цвет кнопки/тему, если это позволяет ваше приложение.

Ответ 14

Вы также можете использовать этот онлайн-инструмент, чтобы настроить свою кнопку http://angrytools.com/android/button/ и использовать android:background="@drawable/custom_btn" для определения настраиваемой кнопки в макете.

Ответ 15

Вы можете настроить тему своей кнопки на

<style name="AppTheme.ButtonBlue" parent="Widget.AppCompat.Button.Colored">
 <item name="colorButtonNormal">@color/HEXColor</item>
 <item name="android:textColor">@color/HEXColor</item>
</style>

Ответ 16

Легкий способ - просто определить пользовательский класс Button, который принимает все свойства, которые вы хотите, такие как радиус, градиент, нажатый цвет, обычный цвет и т.д., а затем просто используйте это в своих макетах XML вместо настройки фона, используя XML. Образец здесь

Это очень полезно, если у вас много кнопок с такими же свойствами, как радиус, выбранный цвет и т.д. Вы можете настроить унаследованную кнопку для обработки этих дополнительных свойств.

Результат (не использовался селектор фона).

Нормальная кнопка

Normal Image

Нажмите кнопку

enter image description here

Ответ 17

То, как я делаю другую стилизованную кнопку, которая работает достаточно хорошо, - это подкласс объекта Button и применение цветового фильтра. Это также относится к включенным и отключенным состояниям, применяя альфа к кнопке.

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

}

Ответ 18

значения\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>

то

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

result