Bagaimana secara pemrograman mengatur drawableLeft pada tombol Android?

442

Saya secara dinamis membuat tombol. Saya menatanya menggunakan XML terlebih dahulu, dan saya mencoba mengambil XML di bawah ini dan membuatnya menjadi program.

<Button
    android:id="@+id/buttonIdDoesntMatter"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:text="buttonName"
    android:drawableLeft="@drawable/imageWillChange"
    android:onClick="listener"
    android:layout_width="fill_parent">
</Button>

Inilah yang saya miliki sejauh ini. Saya bisa melakukan segalanya kecuali yang dapat digambar.

linear = (LinearLayout) findViewById(R.id.LinearView);
Button button = new Button(this);
button.setText("Button");
button.setOnClickListener(listener);
button.setLayoutParams(
    new LayoutParams(
        android.view.ViewGroup.LayoutParams.FILL_PARENT,         
        android.view.ViewGroup.LayoutParams.WRAP_CONTENT
    )
);      

linear.addView(button);
Tim
sumber

Jawaban:

1055

Anda dapat menggunakan setCompoundDrawablesmetode untuk melakukan ini. Lihat contoh di sini . Saya menggunakan ini tanpa menggunakan setBoundsdan itu berhasil. Anda dapat mencoba keduanya.

PEMBARUAN : Menyalin kode di sini jika tautannya tidak aktif

Drawable img = getContext().getResources().getDrawable(R.drawable.smiley);
img.setBounds(0, 0, 60, 60);
txtVw.setCompoundDrawables(img, null, null, null);

atau

Drawable img = getContext().getResources().getDrawable(R.drawable.smiley);
txtVw.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null);

atau

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);
Varun
sumber
@ Varun, @Tigger: Saya memiliki masalah dengan ini: Manajer file saya menunjukkan folder dalam tampilan daftar dengan tampilan teks dan ikon folder sebagai drawableLeft. Saya mencoba saran Anda di sini untuk menetapkan "ikon terlarang" ketika Anda mengklik dalam folder tanpa izin baca, dan itu berhasil. Namun, ketika Anda mengganti folder dan adaptor dimuat ulang, ikon terlarang tetap ada (artinya, drawableLefttidak digambar ulang). Apakah Anda tahu cara mendaftar notifyDataSetChangedjuga untuk drawableLeft, tanpa melakukan loop? Terima kasih!
Luis A. Florit
@ LuisA.Florit Sepertinya Anda memiliki pertanyaan terkait penggambaran ulang Listviewitem saat data berubah - yang tidak benar-benar terkait dengan pertanyaan atau jawaban ini. Saya sarankan Anda memposting pertanyaan, bukan komentar.
Tigger
@ Tigger: Yah, saya mengembalikan ikon menggunakan trik Anda juga, dan loop di atas terlarang. Mungkin ini lebih baik daripada menggambar ulang semua item ListView ... Terima kasih!
Luis A. Florit
3
Saya melihat sesuatu yang aneh di aplikasi saya. Tidak setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.money, 0 )berfungsi, jika saya mendefinisikan drawableRight di layout.xml. Jika saya mengatur ikon asli di dalam onCreate(), maka perubahan berfungsi. Mungkinkah itu terkait dengan API 19?
Suntik
Tautan contoh tidak terbuka. Apakah ada tautan alternatif?
Yogesh Umesh Vaity
100

Cukup Anda bisa mencoba ini juga

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);
Jignesh Ansodariya
sumber
4
R.drawable.smiley harus di tempat 0 pertama (parameter pertama) bukan yang terakhir karena definisi dari metode ini adalah: {public void setCompoundDrawablesWithIntrinsicBounds (kiri, atas atas, int kanan, int bawah)}
arniotaki
Bagaimana saya bisa menambahkan padding di sekitar ini juga? Tidak banyak padding antara drawable dan teks dengan cara ini.
AdamMc331
16

Kotlin Version

Gunakan potongan di bawah ini untuk menambahkan gambar kiri ke tombol:

val drawable = ContextCompat.getDrawable(context, R.drawable.ic_favorite_white_16dp)
button.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)

.

Important Point in Using Android Vector Drawable

Saat Anda menggunakan gambar vektor Android dan ingin memiliki kompatibilitas mundur untuk API di bawah 21 , tambahkan kode berikut ke:

Di tingkat aplikasi build.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

Di kelas Aplikasi:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}
aminografi
sumber
Cara yang lebih sederhana yang juga berfungsi untuk saya: button.setCompoundDrawablesWithIntrinsicBounds (getDrawable (R.drawable.ic_favorite_white_16dp), null, null, null)
juangalf
2
Anda benar, tetapi Context#.getDrawable(resId)sudah usang, jadi menggunakannya dapat menyebabkan beberapa masalah.
aminografi
Bekerja tanpa menambahkan dalam kelas Aplikasi karena saya tidak punya.
Mark Delphi
15

Bagi saya, itu berhasil:

button.setCompoundDrawablesWithIntrinsicBounds(com.example.project1.R.drawable.ic_launcher, 0, 0, 0);
swapnil saha
sumber
13
myEdtiText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);
gnganpath
sumber
4

Saya melakukan ini:

 // Left, top, right, bottom drawables.
            Drawable[] drawables = button.getCompoundDrawables();
            // get left drawable.
            Drawable leftCompoundDrawable = drawables[0];
            // get new drawable.
            Drawable img = getContext().getResources().getDrawable(R.drawable.ic_launcher);
            // set image size (don't change the size values)
            img.setBounds(leftCompoundDrawable.getBounds());
            // set new drawable
            button.setCompoundDrawables(img, null, null, null);
pengguna1564762
sumber
4

Jika Anda menggunakan drawableStart , drawableEnd , drawableTop atau drawableBottom ; Anda harus menggunakan " setCompoundDrawablesRelativeWithIntrinsicBounds "

edittext.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.anim_search_to_close, 0)
Memberikan
sumber
3

Bekerja untukku. Untuk mengatur drawable di sebelah kanan

tvBioLive.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_red_400_24dp, 0)
Shaon
sumber
2

seperti yang ditunjukkan oleh @ Jérémy Reynaud, seperti dijelaskan dalam jawaban ini , cara teraman untuk mengatur drawable kiri tanpa mengubah nilai drawable lainnya (atas, kanan, dan bawah) adalah dengan menggunakan nilai sebelumnya dari tombol dengan setCompoundDrawablesWithIntrinsicBounds :

Drawable leftDrawable = getContext().getResources()
                          .getDrawable(R.drawable.yourdrawable);

// Or use ContextCompat
// Drawable leftDrawable = ContextCompat.getDrawable(getContext(),
//                                        R.drawable.yourdrawable);

Drawable[] drawables = button.getCompoundDrawables();
button.setCompoundDrawablesWithIntrinsicBounds(leftDrawable,drawables[1],
                                               drawables[2], drawables[3]);

Jadi semua gambar Anda sebelumnya akan dipertahankan.

ישו אוהב אותך
sumber
2

Berikut ini adalah cara untuk mengubah warna ikon kiri dalam teks edit dan mengaturnya di sisi kiri.

 Drawable img = getResources().getDrawable( R.drawable.user );
img.setBounds( 0, 0, 60, 60 );
mNameEditText.setCompoundDrawables(img,null, null, null);

int color = ContextCompat.getColor(this, R.color.blackColor);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    DrawableCompat.setTint(img, color);

} else {
    img.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
Rajneesh Shukla
sumber
1

Mungkin bisa membantu:

TextView location;
location=(TextView)view.findViewById(R.id.complain_location);
//in parameter (left,top,right,bottom) any where you wnat to put
location.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.arrow,0);
Muhaiminur Rahman
sumber
1

Tambahkan Ekstensi Kotlin

Jika Anda akan sering melakukan ini, menambahkan ekstensi membuat kode Anda lebih mudah dibaca. Tombol memperluas TextView; gunakan Tombol jika ingin lebih sempit.

fun TextView.leftDrawable(@DrawableRes id: Int = 0) {
    this.setCompoundDrawablesWithIntrinsicBounds(id, 0, 0, 0)
}

Untuk menggunakan ekstensi, cukup panggil

view.leftDrawable(R.drawable.my_drawable)

Kapan saja Anda perlu menghapus, jangan melewati param atau membuat ekstensi lain dipanggil removeDrawables

Gibolt
sumber
0

Coba ini:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
     fillButton[i].setBackground(getBaseContext().getResources().getDrawable(R.drawable.drawable_name));
}
else {
    fillButton[i].setBackgroundColor(Color.argb(255,193,234,203));
}
Maifee Ul Asad
sumber
-8

Coba ini:

((Button)btn).getCompoundDrawables()[0].setAlpha(btn.isEnabled() ? 255 : 100);
pengguna2969017
sumber
myEdtiText.setCompoundDrawablesDenganIntrinsicBounds (R.drawable.smiley, 0, 0, 0); bekerja
Debasish Ghosh