วิธีตั้งโปรแกรม drawableLeft บนปุ่ม Android โดยทางโปรแกรม


442

ฉันกำลังสร้างปุ่มแบบไดนามิก ฉันจัดรูปแบบพวกเขาโดยใช้ XML ก่อนและฉันพยายามที่จะใช้ XML ด้านล่างและทำให้มันเป็นโปรแกรม

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

นี่คือสิ่งที่ฉันมี ฉันสามารถทำทุกอย่างได้

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

คำตอบ:


1054

คุณสามารถใช้setCompoundDrawablesวิธีการนี้ ดูตัวอย่างที่นี่ ฉันใช้สิ่งนี้โดยไม่ใช้setBoundsมันและใช้งานได้ คุณสามารถลองด้วยวิธีใดวิธีหนึ่ง

อัปเดต : การคัดลอกรหัสที่นี่ในกรณีที่ลิงก์หยุดทำงาน

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

หรือ

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

หรือ

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

@Varun, @Tigger: ผมมีปัญหากับเรื่องนี้: โฟลเดอร์ของฉันแสดง filemanager ใน ListView กับ textviews drawableLeftและไอคอนโฟลเดอร์เป็น ฉันลองคำแนะนำของคุณที่นี่เพื่อตั้ง "ไอคอนต้องห้าม" เมื่อคุณคลิกในโฟลเดอร์ที่ไม่มีสิทธิ์อ่านและใช้งานได้ อย่างไรก็ตามเมื่อคุณเปลี่ยนโฟลเดอร์และโหลดอะแดปเตอร์ใหม่ไอคอนต้องห้ามยังคงมีอยู่ (นั่นคือdrawableLeftไม่ได้ถูกวาดขึ้นใหม่) คุณรู้วิธีนำไปใช้notifyDataSetChangedกับdrawableLeft, โดยไม่ทำลูปหรือไม่? ขอบคุณ!
Luis A. Florit

@ LuisA.Florit ดูเหมือนว่าคุณมีคำถามเกี่ยวกับการเขียนListviewรายการใหม่เมื่อข้อมูลเปลี่ยนแปลง - ซึ่งไม่เกี่ยวข้องกับคำถามหรือคำตอบนี้จริงๆ ฉันแนะนำให้คุณโพสต์คำถามแทนความคิดเห็น
ทิกเกอร์

@Tigger: ดีฉันหวนกลับไอคอนโดยใช้เคล็ดลับของคุณด้วยและวนรอบ dirs ต้องห้าม บางทีนี่อาจจะดีกว่าการวาดรายการ ListView ทั้งหมด ... ขอบคุณอีกครั้ง!
Luis A. Florit

3
ฉันเห็นสิ่งแปลก ๆ ในแอพของฉัน setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.money, 0 )ไม่ทำงานถ้าฉันกำหนด drawableRight ใน layout.xml หากฉันตั้งไอคอนดั้งเดิมไว้ภายในonCreate()การเปลี่ยนแปลงจะทำงาน มันเกี่ยวข้องกับ API 19 ไหม
injecteer

ลิงก์ตัวอย่างไม่เปิดขึ้น มีลิงค์ทางเลือกอื่นหรือไม่?
Yogesh Umesh Vaity

100

เพียงคุณสามารถลองสิ่งนี้ได้เช่นกัน

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

4
R.drawable.smiley ควรอยู่ในตำแหน่งของ 0 ตัวแรก (พารามิเตอร์ตัวแรก) ไม่ใช่ตัวสุดท้ายเพราะคำจำกัดความของวิธีนี้คือ: {โมฆะสาธารณะ setCompoundDrawablesWithIntrinsicBounds (int ซ้าย, int ด้านบน, ด้านขวา int, ด้านล่าง int)}
arniotaki

ฉันจะเพิ่มช่องว่างภายในได้อย่างไร ไม่มีช่องว่างภายในมากระหว่าง drawable และข้อความด้วยวิธีนี้
AdamMc331

16

Kotlin Version

ใช้ตัวอย่างด้านล่างเพื่อเพิ่ม drawable ที่เหลือไว้ที่ปุ่ม:

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

.

Important Point in Using Android Vector Drawable

เมื่อคุณใช้Android เวกเตอร์ที่วาดได้และต้องการให้มีความเข้ากันได้แบบย้อนหลังสำหรับAPI ด้านล่าง 21ให้เพิ่มรหัสต่อไปนี้ลงใน:

ในระดับแอปbuild.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

ในชั้นสมัคร:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}

วิธีที่เรียบง่ายและใช้งานได้กับฉัน: button.setCompoundDrawablesWithIntrinsicBounds (getDrawable (R.drawable.ic_favorite_white_16dp), null, null, null)
juangalf

2
คุณพูดถูก แต่Context#.getDrawable(resId)เลิกใช้ดังนั้นการใช้อาจทำให้เกิดปัญหา
อะมิโนกราฟ

ทำงานได้โดยไม่เพิ่มในคลาสแอปพลิเคชันเนื่องจากฉันไม่มี
Mark Delphi



4

ฉันทำอย่างนี้:

 // 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);

4

หากคุณกำลังใช้drawableStart , drawableEnd , drawableTopหรือdrawableBottom ; คุณต้องใช้ " setCompoundDrawablesRelativeWithIntrinsicBounds "

edittext.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.anim_search_to_close, 0)

3

ทำงานให้ฉัน เพื่อตั้งค่า drawable ที่ด้านขวา

tvBioLive.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_red_400_24dp, 0)

2

เป็น @ Jérémyนอร์ดชี้ให้เห็นตามที่อธิบายในเรื่องนี้คำตอบวิธีที่ปลอดภัยที่สุดที่จะตั้ง drawable ซ้ายโดยไม่ต้องเปลี่ยนค่าของภาพวาดอื่น ๆ (บนขวาและล่าง) คือการใช้ค่าก่อนหน้าจากปุ่มที่มี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]);

ดังนั้น drawable ก่อนหน้านี้ทั้งหมดของคุณจะถูกเก็บไว้


2

ต่อไปนี้เป็นวิธีการเปลี่ยนสีของไอคอนด้านซ้ายในการแก้ไขข้อความและตั้งค่าทางด้านซ้าย

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

1

อาจเป็นประโยชน์:

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

1

เพิ่มนามสกุล Kotlin

หากคุณกำลังจะทำสิ่งนี้บ่อยครั้งการเพิ่มส่วนขยายทำให้โค้ดของคุณอ่านง่ายขึ้น ปุ่มขยาย TextView; ใช้ปุ่มถ้าคุณต้องการแคบกว่านี้

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

หากต้องการใช้ส่วนขยายเพียงโทร

view.leftDrawable(R.drawable.my_drawable)

เมื่อใดก็ตามที่คุณต้องการล้างข้อมูลอย่าผ่าน param หรือทำการเรียกนามสกุลอื่น removeDrawables


0

ลองสิ่งนี้:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.