Як програмно встановити dravableLeft на кнопці 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: У мене проблема з цим: мій менеджер файлів показує папки в перегляді списку з переглядами тексту та піктограмою папки як drawableLeft. Я спробував тут ваші пропозиції встановити "заборонену піктограму", коли ви клацаєте в папці без дозволу на читання, і це працює. Однак, коли ви змінюєте папки, і адаптер перезавантажується, заборонений значок зберігається (тобто drawableLeftне перемальовується). Чи знаєте ви, як застосувати notifyDataSetChangedі для drawableLeft, не роблячи циклу? Дякую!
Луїс А. Флорит

@ LuisA.Florit Це здається, що у вас є питання, пов’язані з перемальовуванням Listviewелемента, коли дані змінюються - що насправді не стосується цього питання чи відповіді. Я пропоную вам залишити питання замість коментаря.
Тигр

@Tigger: Ну, я повернув назад іконку, використовуючи трюк, і петлю над забороненими панорами. Можливо, це краще, ніж перемальовувати всі елементи ListView ... Спасибі все одно!
Луїс А. Флорит

3
Я бачу щось дивне у своєму додатку. setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.money, 0 )Чи не працює, якщо я визначити drawableRight в layout.xml. Якщо я встановити оригінал піктограми всередині onCreate(), то зміна працює. Чи може це бути пов'язано з API 19?
інжектор

Приклад посилання не відкривається. Чи є альтернативна посилання?
Йогеш Умеш Ваїті

100

Просто ви можете спробувати і це

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

4
R.dravable.smiley повинен бути на місці першого 0 (перший параметр) не останнім, оскільки визначення цього методу таке: {public void setCompoundDrawablesWithIntrinsicBounds (int зліва, int вгорі, int право, int знизу)}
arniotaki

Як я можу додати оббивки навколо цього теж? Таким чином, між малюнком та текстом не так багато прокладки.
AdamMc331

16

Kotlin Version

Скористайтеся фрагментом нижче, щоб додати кнопочку зліва, яку можна отримати зліва

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

.

Important Point in Using Android Vector Drawable

Коли ви користуєтеся андроїд-вектором для малювання та хочете мати зворотну сумісність для API нижче 21 , додайте такі коди до:

На рівні програми build.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

У класі додатків:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}

Простіший спосіб, який також працює для мене: button.setCompoundDrawablesWithIntrinsicBounds (getDravable (R.dravable.ic_favorite_white_16dp), null, null, null)
juangalf

2
Ви маєте рацію, але Context#.getDrawable(resId)застаріли, тому використання її може спричинити деякі проблеми.
амінографія

Працює без додавання в клас програми, оскільки у мене його немає.
Марк Дельфі

15

Для мене це спрацювало:

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


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

Якщо ви використовуєте dravableStart , dravableEnd , dravableTop або dravableBottom ; ви повинні використовувати " setCompoundDrawablesRelativeWithIntrinsicBounds "

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

3

Працювали для мене. Щоб встановити прапорець праворуч

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

2

як @ Jérémy Reynaud вказує, як описано у цій відповіді , найбезпечніший спосіб встановити лівий малюнок без зміни значень інших рисунків (верхній, правий і нижній), використовуючи попередні значення з кнопки 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]);

Так усі ваші попередні малюнки будуть збережені.


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)

У будь-який час, коли вам потрібно очистити, не передайте парам або не називайте інше розширення 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));
}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.