Як програмно встановити 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.