Farklı renkte standart Android Düğmesi


735

Bir müşterinin markasını daha iyi eşleştirmek için standart bir Android düğmesinin rengini biraz değiştirmek istiyorum.

Bunu şimdiye kadar yapmanın en iyi yolu, Button'nin çekilebilir olanını yer alan çekilebilir olarak değiştirmek 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>

Ancak bunu yapmak için, aslında özelleştirmek istediğim her düğme için üç farklı çekmece oluşturmam gerekiyor (bir tanesi dururken, biri odaklandığında ve biri basıldığında). Bu ihtiyacımdan daha karmaşık ve KURU olmayan görünüyor.

Gerçekten yapmak istediğim tek şey düğmeye bir çeşit renk dönüşümü uygulamak. Bir düğmenin rengini değiştirmemden daha kolay bir yol var mı?


Yanıtlar:


724

Tüm bunların bir dosyada oldukça kolay bir şekilde yapılabileceğini keşfettim. Adlı bir dosyaya aşağıdaki kod gibi bir şey koyun custom_button.xmlve sonra background="@drawable/custom_button"düğme görünümünüzde ayarlayın:

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

43
Arka plan rengi için iyi çalışır - metin rengini aynı şekilde ayarlayabilir misiniz?
Rachel

8
Bu bana "Error: No resource found that matches the given name (at 'color' with value '@color/yellow1')" bu renklerle ilgili referanslar mı veriyor ? Bu işi yapmak için bir res / değerleri / color.xml ihtiyacım var gibi görünüyor
Harry Wood

8
@HarryWood res / değerleri / colors.xml dosyasında bu renkleri tanımlamanız gerekir. Alternatif olarak, bunları test amacıyla "# ff0000", "# 00ff00" ile değiştirin @ cfarm54 Bu dosya res / drawable / custom_button.xml klasörüne @emmby konulmalıdır Kod pasajı için teşekkürler!
espinchi

17
Harika işaretçi, teşekkürler! Ayrıca bunu deneyen diğer insanlar için, seçicideki öğelerin sırası önemlidir. <item> dosyasını ilk durum filtresi olmadan dosyaya koyarsanız, geri kalanını geçersiz kılar.
mikerowehl

9
bu işi yapmak için res / "çekilebilir" klasörünüze custom_button.xml dosyasını yerleştirin ve şu içeriklerle bir res / değerleri / colors.xml dosyası oluşturun: stackoverflow.com/questions/3738886/… - her iki dosyadaki renk adlarını değiştirin çalışmak için
sami

308

Tomasz'ın cevabından sonra, PorterDuff çarpma modunu kullanarak tüm düğmenin gölgesini programlı olarak da ayarlayabilirsiniz. Bu, yalnızca renk tonundan ziyade düğme rengini değiştirir.

Standart gri gölgeli bir düğmeyle başlarsanız:

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

size kırmızı gölgeli bir düğme verecek,

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

size yeşil gölgeli bir düğme verir, burada ilk değer onaltılık biçimde renktir.

Geçerli düğme renk değerini renk değerinizle çarparak çalışır. Eminim bu modlarla yapabileceğiniz çok daha fazla şey vardır.


2
Vay be, sadece denedim ve tamamen harika. Teşekkür ederim! Bir şekilde xml ile başarmanın bir yolu olup olmadığını biliyor musunuz?
emmby

4
Beyler, HTC Desire üzerinde kontrol edin! Farklı standart düğmelere sahiptirler. Bu kodu kullanan düğmelerim, "40dp" gibi belirli bir düzen_genişliği ayarlarken orada çok güzel görünüyor. "Wrap_content" ile sorun değil.
OneWorld

5
Onaylandı, bu çözüm HTC Sense UI üzerinde çok iyi
çalışmıyor

19
Eclipse bunu olası bir düzeltme olarak göstermiyor:import android.graphics.PorterDuff;
Birisi

2
ICS'de çalışmama sorunu olan var mı? Benim için emülatör veya telefon üzerinde çalışmıyor gibi görünüyor ..
Stev_k

149

Mike, renk filtreleriyle ilgilenebilirsin.

Bir örnek:

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

İstediğiniz rengi elde etmek için bunu deneyin.


SetColorFilter yönteminde null iletmeyi deneyin. Denemedim ama işe yarayacak.
Tomasz

6
@ Ayarlanacak ayarlayıcı: button.getBackground (). ClearColorFilter ();
Stan Kurdziel

3
Color sınıfını kullanarak renk seçmenizi öneririm: developer.android.com/reference/android/graphics/Color.html
Mugen

Karanlık temalar için mükemmel! Diğer üst yanıtın (setColorFilter (0xFFFF0000, PorterDuff.Mode.MULTIPLY)) açık temalar için daha iyi çalıştığını varsayıyorum.
java.is.for.desktop

85

Bu, API 15'ten başlayarak mükemmel çalışan benim çözümüm . Bu çözüm, malzeme gibi tüm varsayılan düğme tıklama efektlerini korur RippleEffect. Daha düşük API'larda test etmedim, ancak çalışmalı.

Tek yapmanız gereken:

1) Yalnızca değişen bir stil oluşturun colorAccent:

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

Diğer stillerinizi korumak ThemeOverlay.AppCompatiçin ana AppThemeöğenizi veya ana öğenizi kullanmanızı öneririm .

2) Bu iki satırı buttonwidget'inize ekleyin :

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

Bazen yeni colorAccenttelefonunuz Android Studio Önizleme'de görünmez, ancak uygulamanızı telefonda başlattığınızda renk değişecektir.


Örnek Düğme widget'ı

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

Özel renk ile Örnek Düğmesi


1
Bu çizgi ne yapıyor? "style =" @ style / Widget.AppCompat.Button.Colored ""
Charles Li

2
Bu, stil ve tema arasındaki farkı anlamama yardımcı oldu. Teşekkür ederim.
rpattabi

2
Kabul edilen cevap doğru ama çok eski. Bu basit ve en güncel cevaptır.
布鞋 白 布鞋

Bu cevapla ilgili sorun, ayarın colorAccentdüğmenin arka planından daha fazlasını etkilemesidir.
Blcknx

@Blcknx Ne örneği?
RediOne1

61

Artık Ayrıca AppCompat-V7 en kullanabilirsiniz AppCompatButton ile backgroundTintöznitelik:

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

4
"Android:" ad alanını kullanarak benim için çalışmadı. Ancak bunun yerine "app:" ad alanını kullandığımda işe yaradı.
David Velasquez

@DavidVelasquez Benim için Android Lollipop'ta da benim için çalıştı: isim alanı hiçbir şey değiştirmedi. Yardım için teşekkürler!
Avinash Prabhakar

Bu en basit çözümdür ve kabul edilen cevap olmalıdır. Android'i kullanmak: backgroundTint benim için çalışıyor.
Ramashish Baranwal

1
Olmalı app:backgroundTintyerine android:backgroundTintAppCompat kullanırken.
Hafez Divandari

23

@Conjugatedirection ve @Tomasz'dan önceki yanıtlarda renk filtresi önerisini beğendim; Ancak, şimdiye kadar sağlanan kod beklediğim kadar kolay uygulanmadığını bulundu.

İlk olarak, renk filtresinin nereye uygulanacağı ve temizleneceği belirtilmedi. Bunu yapmak için başka iyi yerler de olabilir, ama benim için aklıma gelen bir OnTouchListener oldu .

Orijinal soruyu okuduğumdan, ideal çözüm herhangi bir görüntü içermeyen bir çözüm olacaktır. @Emmby'den custom_button.xml kullanan kabul edilen yanıt, hedefiniz buysa renk filtrelerinden daha uygun olabilir. Benim durumumda, düğmenin nasıl görünmesi gerektiğine dair bir UI tasarımcısından bir png görüntüsü ile başlıyorum. Düğme arka planını bu görüntüye ayarlarsam, varsayılan vurgu geri bildirimi tamamen kaybolur. Bu kod, bu davranışı programlı bir kararan efektiyle değiştirir.

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

Bunu sadece fikir edinmek için anonim iç sınıf olarak gösterilen çoklu düğmelere uygulama için ayrı bir sınıf olarak çıkardım.


Harika bir çözümdü! Çoğunlukla iOS'ta varsayılan olarak aldığınız etki aynıdır
Christer Nordvik

Ben aynı arka plan ile aynı ekranda 2 düğme ile denedim ve etkisi onTouch
Goofy

16

XML ile renk düğmeleri yapıyorsanız, odaklanmış ve basılı durumunu ayrı bir dosyada belirterek kodu biraz daha temiz hale getirebilir ve yeniden kullanabilirsiniz. Yeşil düğmem şöyle:

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

1
Güzel. nasıl odaklanmış ve preslenmiş devlet düğmeler için standart android tanımları geri referans yapmak olabilir?
larham1

Standart Android düğmeleri 9 yama bitmapleri olarak uygulandığından emin değilim.
haemish

12

Herhangi bir Android sürümü ile çalışan en kısa çözüm:

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

Notlar / Gereksinimler :

  • Kullan app:ad ve değilandroid: ad!
  • uygulama sürümü sürümü> 24.2.0

    bağımlılıklar {derlemek 'com.android.support:appcompat-v7:25.3.1'}

Açıklama : resim açıklamasını buraya girin


1
İlginçtir, benim için app:backgroundTint="@color/my_color"işe yaramadı. android:backgroundTint="@color/my_color"olsa mükemmel çalıştı.
Igor

Bu benim için en kısa ve en temiz çözüm ve hepsi bu.
Marty

11

Bu yaklaşımı kullanıyorum

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>

Yukarıda da görebileceğiniz gibi, düğmem için özel bir stil kullanıyorum. Düğme rengi, vurgu rengine karşılık gelir. android:backgroundGoogle'ın sağladığı dalgalanma efektini kaybetmeyeceğimden, bunu ayarlamaktan çok daha iyi bir yaklaşım olarak görüyorum.


8

Şimdi çok daha kolay bir yol var: android-holo-colors.com

Tüm holo çizilebilir malzemelerin (düğmeler, döndürücüler, ...) renklerini kolayca değiştirmenize izin verecektir. Rengi seçer ve ardından tüm çözünürlükler için çekmeceleri içeren bir zip dosyası indirirsiniz.


8

Bu şekilde kullanın:

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

4

In <Button>kullanım android:background="#33b5e5". ya da daha iyisiandroid:background="@color/navig_button"


3

DroidUX bileşen kütüphanesi vardır ColorButtonhatta Uygulama izin eğer kullanıcı düğmenin rengi / tema ayarlamak için izin böylece, rengini xml tanımı üzerinden ve programlı çalışma zamanında hem de kolaylıkla değiştirilebilir widget'ı.



2

Düğmenizin temasını buna ayarlayabilirsiniz

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

1

Kolay bir yol, yalnızca yarıçap, degrade, basılı renk, normal renk vb. Bir örnek burada

Yarıçap, seçilen renk vb. Gibi aynı özelliklere sahip çok sayıda düğmeniz varsa bu son derece yararlıdır. Bu ek özellikleri işlemek için devralınan düğmenizi özelleştirebilirsiniz.

Sonuç (Arka Plan seçici kullanılmadı).

Normal Düğme

Normal Görüntü

Basılı Düğme

resim açıklamasını buraya girin


0

Oldukça iyi çalışan farklı bir stil düğmesi yapmanın yolu Button nesnesini alt sınıflamak ve bir renk filtresi uygulamaktır. Bu, düğmeye alfa uygulayarak etkin ve devre dışı durumları da işler.

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

}

0

değerlerin \ 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>

sonra:

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

sonuç


0

Malzeme tasarım yönergelerine göre, stili aşağıdaki kod gibi kullanmanız gerekir

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

ve mizanpajda bu özelliği düğmenize ekleyin

    android:theme="@style/MyButton"

0

Basit .. projenize bu bağımlılığı ekleyin ve 1 ile bir düğme oluşturun. Herhangi bir şekil 2. Herhangi bir renk 3. Herhangi bir sınır 4. Malzeme efektleri ile

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" />
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.