Arka plan rengiyle düğmedeki malzeme etkisi


246

Android v21 destek kitaplığını kullanıyorum.

Özel arka plan rengine sahip bir düğme oluşturdum. Arka zemin rengini kullandığımda, dalgalanma, açığa çıkarma gibi malzeme tasarım efektleri gitti (tıklamadaki yükseklik hariç).

 <Button
 style="?android:attr/buttonStyleSmall"
 android:background="?attr/colorPrimary"
 android:textColor="@color/white"
 android:textAllCaps="true"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 />

Arka fon Aşağıdaki normal bir düğmedir ve efektler iyi çalışır.

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:textAllCaps="true"
 android:text="Button1"
/>

Varsayılan düğme


9
Bu, arka planı tüm güzel Malzeme efektleriyle düz bir renkle değiştirdiğiniz için oluşur. Malzeme efektlerini korurken bir düğmeyi nasıl renklendirdiğinize ilişkin olarak, SO'daki hiç kimse bunu anlayamadı.
Nathan Walters

2
@SweetWisher Arka plan rengini değiştirdiğimde düğmeye dalgalanma ve diğer efektler uygulanmaz.
Sathesh

1
@NathanWalters Ama varsayılan gri renk çirkin. :-(
Sathesh

6
İnanın bana, biliyorum ... Bunu nasıl doğru bir şekilde yapılacağını kimin anladığını biliyoruz.
Nathan Walters

Yanıtlar:


431

Kullandığınızda android:background, stilin çoğunu ve bir düğmenin görünüşünü ve hissini boş bir renkle değiştirirsiniz.

Güncelleme: itibarıyla sürümü 23.0.0 sürümü ait AppCompat , yeni vardır Widget.AppCompat.Button.ColoredTemanızın en kullanır tarzı colorButtonNormalengelli renk ve colorAccentetkin renk için.

Bu, doğrudan düğmenize uygulamanızı sağlar

<Button
  ...
  style="@style/Widget.AppCompat.Button.Colored" />

Özel bir seçeneğe ihtiyacınız varsa colorButtonNormalveya bu öneri ve düğmede açıklandığı gibi colorAccenta kullanabilirsiniz .ThemeOverlayandroid:theme

Önceki Cevap

Arka planınız için v21 dizininizde bir çekilebilir kullanabilirsiniz:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?attr/colorControlHighlight">
    <item android:drawable="?attr/colorPrimary"/>
</ripple>

Bu, arka plan renginizin ?attr/colorPrimaryvarsayılanı kullanarak varsayılan dalgalanma animasyonuna ?attr/colorControlHighlightsahip olmasını sağlar (isterseniz temanızda da ayarlayabilirsiniz).

Not: v21'den daha düşük bir değer için özel bir seçici oluşturmanız gerekir:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/primaryPressed" android:state_pressed="true"/>
    <item android:drawable="@color/primaryFocused" android:state_focused="true"/>
    <item android:drawable="@color/primary"/>
</selector>

Varsayılan, basılı ve odaklanmış durum için istediğiniz bazı renkleriniz olduğunu varsayarsak. Şahsen, seçilerek yarı yolda bir dalgalanma ekran görüntüsü aldım ve birincil / odaklanmış durumu bundan çıkardım.


13
Güzel cevap! Tam olarak aradığım şey, proje çekilebilir-v21'de çekilebilir olanı belirlemeye karar vermeden önce temizlemek ve yeniden inşa etmek gerekiyordu.
user1354603


4
@ianhanniballake Bu düğmede köşeleri yuvarlatılmış özelleştirmeyi kaybetmeden bu çalışma tekniğini nasıl birleştireceğimizi merak ediyorum
Joaquin Iurchuk

3
@ianhanniballake sadece bir yorum, dalgalanma altında <item android: drawable ... /> altında saydam bir renk olamaz. Bu durumda dalgalanma gösterilmez. Bunu fark etmem biraz zaman aldı.
Ivan Kušt

2
Appcompat 23.1.1 ve API 22 ile, devre dışı bırakılmış ve etkin durum her ikisi de temanın colorButtonNormal rengini alır.
Rémy DAVID

93

"Malzeme" efektlerini korurken "Düz" düğmeler için özel arka plan sağlamak için başka bir basit çözüm var.

  1. İstediğiniz arka plan ayarlanmış olarak düğmenizi ViewGroup'a yerleştirin
  2. geçerli temadan selectableItemBackground'ı düğmeniz için arka plan olarak ayarlayın (API> = 11)

yani:

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/blue">
    <Button
        style="?android:attr/buttonStyleSmall"
        android:background="?android:attr/selectableItemBackground"
        android:textColor="@android:color/white"
        android:textAllCaps="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Button1"
        />
</FrameLayout>

Düz düğmeler için kullanılabilir , API> = 11 üzerinde çalışır ve> = 21 cihazlarda dalgalanma efekti elde edersiniz, AppCompat da dalgalanmayı desteklemek için güncellenene kadar 21 öncesi düzenli düğmeleri tutar.

SelectableItemBackgroundBorderless öğesini yalnızca> = 21 düğme için de kullanabilirsiniz .


Kelimenin tam anlamıyla kutunun dışına düşündünüz :-) Bu bunu yapmanın bir yolu olmasına rağmen, kod kaplini artırabilir ve stilleri kullanmak önerilen yol olacaktır.
Sathesh

3
Bu renk arka planlı düz bir düğme oluşturur, evet. Ancak oluşturulan düğme bir kare gibi görünür, yuvarlak köşeler ve gölge efektleri yoktur.
Sanket Berde

7
@SanketBerde Kesinlikle. Çünkü "düz" buton bu.
kiruwka

2
Orijinal soru düz bahsetmedi. btw, çözümünüzde <FrameLayout> yerine bir <CardView> üst öğeniz varsa, ortaya çıkan düğme yükseltilir ve gölgeler oluşur. Bu lolipop öncesi versiyonlarda bile çalışır.
Sanket Berde

1
@SanketBerde CardViewyaklaşım hakkında bilmek harika , paylaştığınız için teşekkürler!
kiruwka

88

Özel arka planla yükseltilmiş düğmelere dalgalanma efekti sağlamanın basit ve geriye dönük uyumlu bir yolu.

Düzeniniz şöyle görünmelidir

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/my_custom_background"
    android:foreground="?android:attr/selectableItemBackground"/>

9
Bunu başarmanın en kolay yolu budur. İyi cevap.
Tyler Pfaff

1
api 21+ ama çalışmıyor. Tıklanabilir-gerçek, arka plan - farklı renk, ön plan- belirtilmiş doğrusal düzene uygulanır.
Alex

3
Button bir TextView olduğundan ve bir FrameLayout olmadığından 23'ten foregroundönce bir etkisi yoktur. Google.com/…
androidguy

2
GÜZEL! "Ön plan" bir şey olduğunu bile bilmiyordum!
Eric Schlenz

2
Tıkır tıkır çalışıyor..!
Kannan

25

Bugün bu problemle karşılaştım ve aslında v22 kütüphanesi ile oynadım.

Stilleri kullandığınızı varsayarsanız, colorButtonNormalözelliği ayarlayabilirsiniz ve düğmeler varsayılan olarak bu rengi kullanır.

<style name="AppTheme" parent="BaseTheme">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryDark">@color/primaryColorDark</item>
    <item name="colorAccent">@color/accentColor</item>
    <item name="colorButtonNormal">@color/primaryColor</item>
</style>

Bunun dışında hala düğme için bir stil yapabilirsiniz, ardından bir renk yelpazesine ihtiyacınız varsa (test etmediniz, sadece spekülasyon) düğme başına kullanın.

V21 stilinizdekiandroid: öğe adlarından önce eklemeyi unutmayın .


Renkli düğmeler için diğer Robert'ın cevabına bakınız: stackoverflow.com/a/31825439/1617737
ban-geoengineering

Arka plan rengi ayarlandığında, düğme metin rengini belirtmek için yukarıdaki kod bloğunda kullanabileceğim genel bir özellik de var mı?
ban-geoengineering

24

AppCompat (22.1.1+) ile şöyle bir stil ekleyebilirsiniz:

<style name="MyGreenButton">
    <item name="colorButtonNormal">#009900</item>
</style>

Ve sadece stili uygulayarak kullanın:

<android.support.v7.widget.AppCompatButton
    style="@style/MyGreenButton"
    android:layout_width="match_width"
    android:layout_height="wrap_content"
    android:text="A Green Button"
    />

Programlı olarak rengi değiştirerek, rengi güncellemenin tek yolunun (API 15 veya 16'da) bunun yerine 'arka plan renk tonu listesini' kullanmak olduğunu buldum. API 21 cihazlarındaki güzel radyal animasyonu kaldırmaz:

ColorStateList colorStateList = new ColorStateList(new int[][] {{0}}, new int[] {0xFF009900}); // 0xAARRGGBB
button.setSupportBackgroundTintList(colorStateList);

Çünkü button.setBackground(...)ve button.getBackground().mutate().setColorFilter(...)API 15 ve 16'daki düğme rengini API 21'deki gibi değiştirmeyin.


1
Çok teşekkür ederim, benim için mükemmel çalıştı (AppCompat inflater'ın yerini AppCompatButton ile değiştirirken xml düzenlerinde Button kullansanız bile)
Louis CAD

1
Sadece bir rengin ColorStateList.valueOf( ... )basitliğini ColorStateListoluşturmak için kullanın .
Taig

colorAccent ve rippleColor tarzda çalışmıyor
Yar

Bu gönderi için teşekkürler. Benim için ne işe yaradı: ViewCompat.setBackgroundTintList(myButton, ColorStateList.valueOf(myColor); Javadoc setSupportBackgroundTintList, bunun bu şekilde adlandırılması gerektiğini söylüyor.
JerabekJakub

22

@ İanhanniballake'in cevabı kesinlikle doğru ve basittir. Ama anlamam birkaç gün sürdü. Cevabını anlamayan biri için işte daha ayrıntılı uygulama

<Button
        android:id="@+id/btn"
        style="@style/MaterialButton"
        ... />


<style name="MaterialButton" parent="Widget.AppCompat.Button.Colored">
    <item name="android:theme">@style/Theme.MaterialButton</item>
   ...
</style>


<style name="Theme.MaterialButton" parent="YourTheme">
    <item name="colorAccent">@color/yourAccentColor</item>
    <item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>

=== Ya ===

<Button
        android:id="@+id/btn"
        style="@style/Widget.AppCompat.Button.Colored"
        android:theme="@style/Theme.MaterialButton" />

<style name="Theme.MaterialButton" parent="YourTheme">
    <item name="colorAccent">@color/yourAccentColor</item>
    <item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>

5
Cevabınız benim için bulmacanın son parçasıydı. colorButtonNormalTemel temada da yazılabilir @style/AppTheme. Bu, düğmeleri uygun şekilde renklendirmek için AppCompat'a varsayılan bir renk verir. Ve sonra cevabınızı ayrı ayrı bir görünüm teması için kullanabilirsiniz.
Siddharth Pant

1
Yoksa android:theme="Theme.MaterialButton"ya daandroid:theme="@style/Theme.MaterialButton"
osrl

1
@osrl Öyle android:theme="@style/Theme.MaterialButton". Doğruluğun için teşekkürler.
Frank Nguyen

12

BackgroundTint ve ön plan kullandım:

<Button
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:backgroundTint="@color/colorAccent"
    android:foreground="?android:attr/selectableItemBackground"
    android:textColor="@android:color/white"
    android:textSize="10sp"/>

afaik backgroundTint standart dalgalanmayı geçersiz kılmadığından ön plan niteliğine gerek yoktur
Julian Os

7

Bu yazıya ListView, Öğemin arka plan rengine sahip olmanın bir yolunu arıyorum , ancak dalgalanmayı korudum.

Ben sadece bir arka plan olarak benim renk ve ön plan olarak selectableItemBackground ekledi:

<style name="my_list_item">
    <item name="android:background">@color/white</item>
    <item name="android:foreground">?attr/selectableItemBackground</item>
    <item name="android:layout_height">@dimen/my_list_item_height</item>
</style>

ve bir cazibe gibi çalışıyor. Aynı teknik düğmeler için de kullanılabilir. İyi şanslar :)



6

ImageButton ile ilgileniyorsanız bu basit şeyi deneyebilirsiniz:

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@android:drawable/ic_button"
    android:background="?attr/selectableItemBackgroundBorderless"
/>

5

v22.1ait appcompat-v7bazı yeni olanaklar sundu. Artık yalnızca bir görünüme belirli bir tema atamak mümkündür.

Kullanım dışı kullanım: Araç Çubuğunu şekillendirmek için tema. Artık android: temayı tüm API seviye 7 ve üstü cihazlarda araç çubukları için ve android: tema desteği API seviyesi 11 ve üstü cihazlarda tüm widget'lar için kullanabilirsiniz.

Bu nedenle, global bir temada istenen rengi ayarlamak yerine, yeni bir tema oluşturup yalnızca Button

Misal:

<style name="MyColorButton" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorButtonNormal">@color/myColor</item>
</style>

Ve bu stili, Button

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 android:theme="@style/MyColorButton"/>

4

Üçüncü taraf bir kitaplık kullanmayı tercih ediyorsanız, traex / RippleEffect'e göz atın . HERHANGİ bir görünüme sadece birkaç satır kodla bir Dalgalanma efekti eklemenizi sağlar . Sadece xml mizanpaj dosyanızda, bir com.andexert.library.RippleViewkapsayıcıyla dalgalanma efekti olmasını istediğiniz öğeyi sarmanız yeterlidir .

Ek bir bonus olarak Min SDK 9 gerektirir, böylece işletim sistemi sürümlerinde tasarım tutarlılığına sahip olabilirsiniz.

İşte kütüphanelerin GitHub repo'sundan alınan bir örnek:

<com.andexert.library.RippleView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:rv_centered="true">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@android:drawable/ic_menu_edit"
        android:background="@android:color/holo_blue_dark"/> 

</com.andexert.library.RippleView>

RippleView öğesini bu özniteliği ekleyerek dalgalanma rengini değiştirebilirsiniz: app:rv_color="@color/my_fancy_ripple_color


3
<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="#fff"
    android:textColor="#000"
    android:text="test"/>

kullanım

xmlns:app="http://schemas.android.com/apk/res-auto"

ve lolipop öncesi renk kabul edecek


2

Büyük öğreticide açıklanan iki yaklaşım var: Alex Lockwood: http://www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html :

Yaklaşım # 1: Düğmenin arka plan rengini bir ThemeOverlay ile değiştirme

<!-- res/values/themes.xml -->
<style name="RedButtonLightTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/googred500</item>
</style>

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:theme="@style/RedButtonLightTheme"/>

Yaklaşım # 2: AppCompatButton'un arka plan renk tonunu ayarlama

<!-- res/color/btn_colored_background_tint.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Disabled state. -->
    <item android:state_enabled="false"
          android:color="?attr/colorButtonNormal"
          android:alpha="?android:attr/disabledAlpha"/>

    <!-- Enabled state. -->
    <item android:color="?attr/colorAccent"/>

</selector>

<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="@color/btn_colored_background_tint"/>

2

Programlı olarak renkleri uygulama:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {

    ColorStateList colorStateListRipple = new ColorStateList(
            new int[][] {{0}},
            new int[] {Color.WHITE} // ripple color
            );

    RippleDrawable rippleDrawable = (RippleDrawable) myButton.getBackground();
    rippleDrawable.setColor(colorStateListRipple);
    myButton.setBackground(rippleDrawable); // applying the ripple color
}

ColorStateList colorStateList = new ColorStateList(
        new int[][]{
                new int[]{android.R.attr.state_pressed}, // when pressed
                new int[]{android.R.attr.state_enabled}, // normal state color
                new int[]{} // normal state color
        },
        new int[]{
                Color.CYAN, // when pressed
                Color.RED, // normal state color
                Color.RED // normal state color
        }
);

ViewCompat.setBackgroundTintList(myButton, colorStateList); // applying the state colors

-1

Bunu denedim:

android:backgroundTint:"@color/mycolor"

background özelliğini değiştirmek yerine. Bu, malzeme etkisini ortadan kaldırmaz.


Bu, Lollipop öncesi cihazlar için çalışmaz (% 70 pazar payı). Aslında destekleniyor ama Android Studio şu anda android öneki olmadan kullanırken hala hatalar gösteriyor.
Siddharth Pant
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.