Tombol Android standar dengan warna berbeda

735

Saya ingin sedikit mengubah warna tombol Android standar agar lebih cocok dengan pencitraan merek klien.

Cara terbaik yang saya temukan untuk melakukan ini sejauh ini adalah mengubah Buttondrawable drawable menjadi drawable yang terletak di 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>

Tetapi melakukan hal itu mengharuskan saya untuk membuat tiga drawable berbeda untuk setiap tombol yang ingin saya sesuaikan (satu untuk tombol saat istirahat, satu saat fokus, dan satu lagi saat ditekan). Tampaknya lebih rumit dan tidak kering daripada yang saya butuhkan.

Yang saya benar-benar ingin lakukan adalah menerapkan semacam transformasi warna pada tombol. Apakah ada cara yang lebih mudah untuk mengubah warna tombol daripada yang saya lakukan?

emmby
sumber
Dan di sini juga android.onyou.ch/2011/01/25/…
Pankaj Kumar

Jawaban:

724

Saya menemukan bahwa ini semua dapat dilakukan dalam satu file dengan cukup mudah. Masukkan sesuatu seperti kode berikut dalam file bernama custom_button.xmldan kemudian atur background="@drawable/custom_button"di tampilan tombol Anda:

<?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>
emmby
sumber
43
Itu bekerja dengan baik untuk warna latar belakang - dapatkah Anda mengatur warna teks dengan cara yang sama?
Rachel
8
Ini memberi saya "Error: No resource found that matches the given name (at 'color' with value '@color/yellow1')" Apakah referensi ini untuk warna bawaan? sepertinya saya perlu res / values ​​/ color.xml untuk membuat ini bekerja
Harry Wood
8
@ HarryWood Anda harus menentukan warna-warna itu di res / values ​​/ colors.xml Anda. Atau, gantilah dengan "# ff0000", "# 00ff00", untuk keperluan pengujian @ cfarm54 File itu harus dimasukkan ke dalam folder res / drawable / custom_button.xml @emmby Terima kasih atas cuplikan kode!
espinchi
17
Pointer yang bagus, terima kasih! Juga perhatikan untuk orang lain di luar sana yang mencoba ini, urutan item dalam pemilih sangat penting. Jika Anda meletakkan <item> tanpa filter keadaan terlebih dahulu dalam file itu akan menimpa sisanya.
mikerowehl
9
untuk membuatnya bekerja, masukkan custom_button.xml ke dalam folder res / "drawable" - dan buat file res / values ​​/ colors.xml dengan konten ini: stackoverflow.com/questions/3738886/… - ubah nama warna di kedua file tersebut untuk membuatnya bekerja
sami
308

Sebagai lanjutan dari jawaban Tomasz, Anda juga dapat secara program mengatur warna seluruh tombol menggunakan mode pengganda PorterDuff. Ini akan mengubah warna tombol daripada hanya warna.

Jika Anda mulai dengan tombol berarsir abu-abu standar:

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

akan memberi Anda tombol berbayang merah,

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

akan memberi Anda tombol hijau berbayang dll., di mana nilai pertama adalah warna dalam format hex.

Ini bekerja dengan mengalikan nilai warna tombol saat ini dengan nilai warna Anda. Saya yakin ada banyak lagi yang dapat Anda lakukan dengan mode ini.

pengarahan terkonjugasi
sumber
2
Wow, baru saja mencobanya dan itu benar-benar fantastis. Terima kasih! Apakah Anda tahu kalau ada cara untuk melakukannya via xml?
emmby
4
Guys, periksa di HTC Desire! Mereka memiliki tombol standar yang berbeda. Tombol saya menggunakan kode ini terlihat luar biasa di sana KETIKA mengatur layout_width tertentu seperti "40dp". Dengan "wrap_content" tidak apa-apa.
OneWorld
5
Dikonfirmasi, solusi ini tidak bekerja dengan baik pada HTC Sense UI
emmby
19
Eclipse tidak menunjukkan ini sebagai kemungkinan perbaikan:import android.graphics.PorterDuff;
Seseorang di suatu tempat
2
Adakah yang punya masalah dengan ini tidak bekerja di ICS? Tampaknya tidak berfungsi pada emulator atau telepon untuk saya ..
Stev_k
149

Mike, Anda mungkin tertarik dengan filter warna.

Sebuah contoh:

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

coba ini untuk mencapai warna yang Anda inginkan.

Tomasz
sumber
Coba lewati nol dalam metode setColorFilter. Belum mencobanya tetapi harus berhasil.
Tomasz
6
@Pacerier untuk menghapus: button.getBackground (). ClearColorFilter ();
Stan Kurdziel
3
Saya sarankan memilih warna menggunakan kelas Warna: developer.android.com/reference/android/graphics/Color.html
Mugen
Sempurna untuk tema gelap! Saya berasumsi bahwa jawaban teratas lainnya (setColorFilter (0xFFFF0000, PorterDuff.Mode.MULTIPLY)) berfungsi lebih baik untuk tema ringan.
java.is.for.desktop
85

Ini adalah solusi saya yang berfungsi sempurna mulai dari API 15 . Solusi ini menjaga semua efek klik tombol standar, seperti materiRippleEffect . Saya belum mengujinya pada API yang lebih rendah, tetapi harus berfungsi.

Yang perlu Anda lakukan adalah:

1) Buat gaya yang hanya berubah colorAccent:

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

Saya sarankan menggunakan ThemeOverlay.AppCompatatau utama Anda AppThemesebagai orang tua, untuk menjaga sisa gaya Anda.

2) Tambahkan dua baris ini ke buttonwidget Anda :

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

Terkadang baru Anda colorAccenttidak ditampilkan di Android Studio Preview, tetapi saat Anda meluncurkan aplikasi di telepon, warnanya akan berubah.


Widget Tombol Sampel

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

Tombol Sampel dengan warna khusus

RediOne1
sumber
1
Apa yang dilakukan garis ini? "style =" @ style / Widget.AppCompat.Button.Colored ""
Charles Li
2
Ini membantu saya untuk memahami perbedaan antara gaya dan tema. Terima kasih.
rpattabi
2
Jawaban yang diterima benar tetapi terlalu tua. Jawaban ini sederhana dan paling mutakhir.
正宗 白 布鞋
Masalah dengan jawaban ini adalah, bahwa pengaturan colorAccentmemengaruhi lebih dari sekadar latar belakang tombol.
Blcknx
@Blcknx Apa misalnya?
RediOne1
61

Anda sekarang dapat juga menggunakan appcompat-v7 ini AppCompatButton dengan backgroundTintatribut:

<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"/>
Nilhcem
sumber
4
Tidak berfungsi untuk saya menggunakan namespace "android:". Tapi itu berhasil ketika saya menggunakan namespace "app:" sebagai gantinya.
David Velasquez
@ DavidVelasquez Itu bekerja untuk saya juga di Android Lollipop sementara android: namespace tidak mengubah apa pun. Terima kasih untuk bantuannya!
Avinash Prabhakar
Ini adalah solusi paling sederhana dan harus menjadi jawaban yang diterima. Menggunakan android: backgroundTint bekerja untuk saya.
Ramashish Baranwal
1
Harus app:backgroundTintbukan android:backgroundTintsaat menggunakan AppCompat.
Hafez Divandari
23

Saya suka saran filter warna dalam jawaban sebelumnya dari @conjugatedirection dan @Tomasz; Namun, saya menemukan bahwa kode yang diberikan sejauh ini tidak semudah yang saya harapkan.

Pertama, tidak disebutkan di mana menerapkan dan menghapus filter warna. Mungkin ada tempat-tempat bagus lain untuk melakukan ini, tetapi yang terlintas di benak saya adalah OnTouchListener .

Dari bacaan saya tentang pertanyaan awal, solusi ideal adalah solusi yang tidak melibatkan gambar apa pun. Jawaban yang diterima menggunakan custom_button.xml dari @emmby mungkin lebih cocok daripada filter warna jika itu adalah tujuan Anda. Dalam kasus saya, saya mulai dengan gambar png dari desainer UI tentang seperti apa bentuk tombol itu. Jika saya mengatur latar belakang tombol untuk gambar ini, umpan balik sorotan default hilang sepenuhnya. Kode ini menggantikan perilaku itu dengan efek penggelapan program.

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

Saya mengekstraksi ini sebagai kelas terpisah untuk aplikasi ke beberapa tombol - ditampilkan sebagai kelas dalam anonim hanya untuk mendapatkan ide.

Stan Kurdziel
sumber
Itu solusi hebat! Sebagian besar pengaruhnya sama seperti yang Anda dapatkan di iOS secara default, seperti itulah yang disukai para desainer :-)
Christer Nordvik
Saya telah mencoba ini dengan 2 tombol di layar yang sama dengan latar belakang yang sama dan efeknya berlaku untuk kedua tombol onTouch
Goofy
16

Jika Anda membuat tombol warna dengan XML, Anda dapat membuat kode sedikit lebih bersih dengan menetapkan status fokus dan ditekan dalam file terpisah dan menggunakannya kembali. Tombol hijau saya terlihat seperti ini:

<?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>
Hem
sumber
1
bagus. bagaimana kita bisa membuat negara yang fokus dan ditekan merujuk kembali ke definisi android standar untuk tombol?
larham1
Saya cukup yakin Anda tidak melakukannya karena tombol Android standar diimplementasikan sebagai bitmap 9-patch.
haemish
12

Solusi terpendek yang bekerja dengan semua versi Android:

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

Catatan / Persyaratan :

  • Gunakan app:namespace dan tidak yang android:namespace!
  • versi appcompat> 24.2.0

    dependencies {compile 'com.android.support:appcompat-v7:25.3.1'}

Penjelasan : masukkan deskripsi gambar di sini

pengguna1185087
sumber
1
Menariknya, bagi saya app:backgroundTint="@color/my_color"tidak berhasil. android:backgroundTint="@color/my_color"bekerja dengan baik.
Igor
Ini adalah solusi terpendek dan terbersih untuk saya dan itu saja.
Marty
11

Saya menggunakan pendekatan ini

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>

Seperti yang dapat Anda lihat dari atas, saya menggunakan gaya khusus untuk tombol saya. Warna tombol sesuai dengan warna aksen. Saya menemukan ini pendekatan yang jauh lebih baik daripada pengaturan android:backgroundkarena saya tidak akan kehilangan efek riak yang disediakan Google.

Kelok Chan
sumber
8

Ada cara yang lebih mudah sekarang: android-holo-colors.com

Ini akan memungkinkan Anda mengubah warna semua drawable holo (tombol, pemintal, ...) dengan mudah. Anda memilih warna dan kemudian mengunduh file zip yang berisi drawables untuk semua resolusi.

Dalma
sumber
8

Gunakan dengan cara ini:

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

Sedang <Button>digunakan android:background="#33b5e5". atau lebih baikandroid:background="@color/navig_button"

lalitm
sumber
3

The DroidUX komponen perpustakaan memiliki ColorButtonwidget yang warnanya dapat diubah dengan mudah, baik melalui definisi xml dan pemrograman pada waktu berjalan, sehingga Anda bahkan dapat membiarkan pengguna untuk mengatur warna / tema tombol jika aplikasi Anda memungkinkan.

Ricky Lee
sumber
3

Anda juga dapat menggunakan alat online ini untuk menyesuaikan tombol Anda http://angrytools.com/android/button/ dan gunakan android:background="@drawable/custom_btn"untuk menentukan tombol yang disesuaikan pada tata letak Anda.

JRE.exe
sumber
2

Anda dapat mengatur tema tombol Anda untuk ini

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

Cara mudah adalah dengan hanya mendefinisikan kelas Tombol kustom yang menerima semua properti yang Anda inginkan seperti jari-jari, gradien, warna yang ditekan, dll warna normal dan kemudian hanya menggunakannya dalam tata letak XML Anda alih-alih mengatur latar belakang menggunakan XML. Sampel ada di sini

Ini sangat berguna jika Anda memiliki banyak tombol dengan properti yang sama seperti jari-jari, warna yang dipilih, dll. Anda dapat menyesuaikan tombol yang diwarisi untuk menangani properti tambahan ini.

Hasil (Tidak ada pemilih Latar Belakang digunakan).

Tombol Normal

Gambar Normal

Tombol ditekan

masukkan deskripsi gambar di sini

redDragonzz
sumber
0

Cara saya melakukan tombol gaya berbeda yang bekerja cukup baik adalah dengan subklas objek Tombol dan menerapkan filter warna. Ini juga menangani keadaan yang diaktifkan dan dinonaktifkan dengan menerapkan alfa ke tombol.

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

}
Matthew Cawley
sumber
0

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>

kemudian:

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

hasil

Milan Hlinák
sumber
0

Per pedoman desain bahan, Anda perlu menggunakan gaya seperti kode di bawah ini

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

dan dalam tata letak tambahkan properti ini ke tombol Anda

    android:theme="@style/MyButton"
Shivam
sumber
0

Sederhana .. tambahkan ketergantungan ini dalam proyek Anda dan buat tombol dengan 1. Bentuk apa saja 2. Warna apa saja 3. Batas apa saja 4. Dengan efek material

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" />
Manoj Bhadane
sumber