Стандартная кнопка Android с другим цветом - PullRequest
718 голосов
/ 05 октября 2009

Я бы хотел немного изменить цвет стандартной кнопки 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>

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

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

Ответы [ 20 ]

711 голосов
/ 13 ноября 2009

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

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

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

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

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

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

даст вам зеленую кнопку и т. Д., Где первое значение - это цвет в шестнадцатеричном формате.

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

147 голосов
/ 10 августа 2010

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

Пример:

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

попробуйте это, чтобы получить цвет, который вы хотите.

82 голосов
/ 19 июля 2016

Это мое решение, которое отлично работает, начиная с из 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" />

Sample Button with custom color

56 голосов
/ 16 января 2016

Теперь вы также можете использовать 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"/>
22 голосов
/ 17 июня 2012

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

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

16 голосов
/ 16 декабря 2011

Если вы создаете цветные кнопки с 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>
12 голосов
/ 04 мая 2017

Самое короткое решение, которое работает с любой версией 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

9 голосов
/ 05 ноября 2015

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

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.

8 голосов
/ 14 июня 2013

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...