Làm cách nào để thiết lập chương trình drawableLeft trên nút Android?


442

Tôi đang tự động tạo các nút. Tôi đã tạo kiểu cho chúng bằng cách sử dụng XML trước tiên và tôi đang cố gắng lấy XML bên dưới và biến nó thành chương trình.

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

Đây là những gì tôi có cho đến nay. Tôi có thể làm mọi thứ nhưng có thể rút ra được.

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

Câu trả lời:


1054

Bạn có thể sử dụng setCompoundDrawablesphương pháp để làm điều này. Xem ví dụ ở đây . Tôi đã sử dụng nó mà không sử dụng setBoundsvà nó đã làm việc. Bạn có thể thử một trong hai cách.

CẬP NHẬT : Sao chép mã ở đây khi liên kết đi xuống

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

hoặc là

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

hoặc là

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

@Varun, @Tigger: Tôi gặp vấn đề với điều này: Trình quản lý tệp của tôi hiển thị các thư mục trong chế độ xem với các chế độ xem văn bản và biểu tượng thư mục dưới dạng a drawableLeft. Tôi đã thử các đề xuất của bạn ở đây để đặt "biểu tượng bị cấm" khi bạn nhấp vào thư mục mà không có quyền đọc và nó hoạt động. Tuy nhiên, khi bạn thay đổi thư mục và bộ điều hợp được tải lại, biểu tượng bị cấm vẫn tồn tại (nghĩa là drawableLeftkhông được vẽ lại). Bạn có biết làm thế nào để áp dụng notifyDataSetChangedcũng cho drawableLeft, mà không làm một vòng lặp? Cảm ơn!
Luis A. Florit

@ LuisA.Florit Có vẻ như bạn có một câu hỏi liên quan đến việc vẽ lại một Listviewmục khi dữ liệu thay đổi - điều này không thực sự liên quan đến câu hỏi hoặc câu trả lời này. Tôi đề nghị bạn gửi một câu hỏi thay vì một bình luận.
Kích hoạt

@Tigger: Chà, tôi cũng đã hoàn nguyên biểu tượng bằng cách sử dụng mánh khóe của bạn và một vòng lặp trên các thư mục bị cấm. Có lẽ điều này tốt hơn là vẽ lại tất cả các mục ListView ... Dù sao cũng cảm ơn!
Luis A. Florit

3
Tôi đang thấy một cái gì đó kỳ lạ trong ứng dụng của mình. Cái setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.money, 0 )này không hoạt động, nếu tôi định nghĩa drawableRight trong layout.xml. Nếu tôi đặt biểu tượng gốc bên trong onCreate(), thì thay đổi sẽ hoạt động. Nó có thể liên quan đến API 19 không?
tiêm chích

Liên kết ví dụ không mở. Có bất kỳ liên kết thay thế?
Yogesh Umesh Vaity

100

Đơn giản là bạn cũng có thể thử cái này

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

4
R.drawable.smiley phải ở vị trí của 0 đầu tiên (tham số đầu tiên) chứ không phải cuối cùng vì định nghĩa của phương thức này là: {public void setCompoundDrawablesWithIntrinsicBound (int left, int top, int right, int bottom)}
arniotaki

Làm thế nào tôi có thể thêm phần đệm xung quanh này, quá? Không có nhiều phần đệm giữa chữ có thể vẽ và văn bản theo cách này.
AdamMc331

16

Kotlin Version

Sử dụng đoạn mã dưới đây để thêm một bên trái có thể rút vào nút:

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

.

Important Point in Using Android Vector Drawable

Khi bạn đang sử dụng một vectơ android có thể vẽ và muốn có khả năng tương thích ngược cho API dưới 21 , hãy thêm các mã sau vào:

Ở cấp độ ứng dụng build.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

Trong lớp Ứng dụng:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}

Một cách đơn giản hơn cũng phù hợp với tôi: button.setCompoundDrawablesWithIntrinsicBound (getDrawable (R.drawable.ic_favorite_white_16dp), null, null, null)
juangalf

2
Bạn đúng, nhưng Context#.getDrawable(resId)không được dùng nữa, vì vậy sử dụng nó có thể gây ra một số vấn đề.
aminography

Hoạt động mà không cần thêm vào lớp Ứng dụng vì tôi không có.
Đánh dấu Delphi

15

Đối với tôi, nó đã làm việc:

button.setCompoundDrawablesWithIntrinsicBounds(com.example.project1.R.drawable.ic_launcher, 0, 0, 0);

13
myEdtiText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

4

Tôi đã làm điều này:

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

Nếu bạn đang sử dụng drawableStart , drawableEnd , drawableTop hoặc drawableBottom ; bạn phải sử dụng " setCompoundDrawablesRelativeWithIntrinsicBound "

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

3

Đã làm cho tôi. Để đặt drawable ở bên phải

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

2

như @ Jérémy Reynaud chỉ ra, như được mô tả trong câu trả lời này , cách an toàn nhất để đặt drawable bên trái mà không thay đổi giá trị của các drawable khác (trên, phải và dưới) là bằng cách sử dụng các giá trị trước đó từ nút với setCompoundDrawablesWithIntrinsicBound :

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

Vì vậy, tất cả các drawable trước của bạn sẽ được bảo tồn.


2

Sau đây là cách thay đổi màu sắc của biểu tượng bên trái trong văn bản chỉnh sửa và đặt nó ở bên trái.

 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

Có thể hữu ích:

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

Thêm tiện ích mở rộng Kotlin

Nếu bạn sẽ làm điều này thường xuyên, việc thêm một tiện ích mở rộng giúp mã của bạn dễ đọc hơn. Nút mở rộng TextView; sử dụng Nút nếu bạn muốn hẹp hơn.

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

Để sử dụng tiện ích mở rộng, chỉ cần gọi

view.leftDrawable(R.drawable.my_drawable)

Bất cứ khi nào bạn cần xóa, đừng vượt qua một thông số hoặc thực hiện một tiện ích mở rộng khác được gọi là removeDrawables


0

Thử cái này:

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

-8

Thử cái này:

((Button)btn).getCompoundDrawables()[0].setAlpha(btn.isEnabled() ? 255 : 100);

myEdtiText.setCompoundDrawablesWithIntrinsicBound (R.drawable.smiley, 0, 0, 0); hoạt động
Debasish Ghosh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.