Вопрос

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

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

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

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

Это было полезно?

Решение

Я обнаружил, что все это можно довольно легко сделать в одном файле.Поместите что-то вроде следующего кода в файл с именем 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>

Другие советы

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

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

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

даст вам красную заштрихованную кнопку,

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

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

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

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

Пример:

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

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

Это мое решение, которое отлично работает, начиная из API 15.Это решение сохраняет все эффекты нажатия кнопок по умолчанию, такие как material 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, но когда вы запустите свое приложение на телефоне, цвет изменится.


Пример виджета кнопки

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

Sample Button with custom color

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

Мне нравится предложение о цветовом фильтре в предыдущих ответах от @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();
    }
});

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

Если вы создаете цветные кнопки с помощью 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>

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

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

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

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

    зависимости { скомпилируйте 'com.android.support:appcompat-v7:25.3.1' }

Объяснение: enter image description here

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

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.

Теперь есть гораздо более простой способ : android-holo-colors.com

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

Используйте это таким образом:

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

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

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

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

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

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

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

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

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

Обычная Кнопка

Normal Image

Нажатая кнопка

enter image description here

Способ, которым я создаю кнопку в другом стиле, которая работает довольно хорошо, - это подкласс объекта 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;
        }
    }

}

values\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

Согласно рекомендациям material design, вам необходимо использовать стиль, подобный приведенный ниже код

<style name="MyButton" parent="Theme.AppCompat.Light>
    <item name="colorControlHighlight">#F36F21</item>
    <item name="colorControlHighlight">#FF8D00</item>
</style>

и в layout добавьте это свойство к вашей кнопке

    android:theme="@style/MyButton"

Это просто..добавьте эту зависимость в свой проект и создайте кнопку с 1.Любая форма 2.Любой цвет 3.Любая граница 4.С материальными эффектами

https://github.com/manojbhadane/QButton

<com.manojbhadane.QButton
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="OK"
       app:qb_backgroundColor="@color/green"
       app:qb_radius="100"
       app:qb_strokeColor="@color/darkGreen"
       app:qb_strokeWidth="5" />
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top