Установить цвет формы Android программно


168

Я редактирую, чтобы сделать вопрос проще, надеясь, что это поможет найти точный ответ.

Скажем, у меня есть следующая ovalформа:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:angle="270"
           android:color="#FFFF0000"/>
    <stroke android:width="3dp"
            android:color="#FFAA0055"/>
</shape>

Как установить цвет программно, из класса занятий?


Что вы устанавливаете для этого?
— Викрам

Drawable является ovalи является фоном ImageView.
— Кот Мунио

Если заданный вопрос слишком сложен, есть ли способ нарисовать несколько изображений на холсте и установить конечный продукт со слоями в качестве фона вида?
— Кот Мунио

Вы можете достичь этого, расширяя Viewкласс и используя его в качестве baseпредставления в макете, который позволяет перекрывать виджеты ( RelativeLayout, FrameLayout). Внутри этого расширенного Viewкласса вы можете draw multiple images onto a canvas. Но, прежде чем сделать это, взгляните на это -> Ссылка (если вы еще этого не сделали).
— Викрам

Ответы:


266

Примечание . Ответ был обновлен, чтобы охватить сценарий, к которому backgroundотносится экземпляр ColorDrawable. Спасибо Тайлеру Пфаффу за то, что указал на это.

Drawable является овалом и является фоном ImageView

Получить Drawableот imageViewиспользования getBackground():

Drawable background = imageView.getBackground();

Сверьтесь с обычными подозреваемыми:

if (background instanceof ShapeDrawable) {
    // cast to 'ShapeDrawable'
    ShapeDrawable shapeDrawable = (ShapeDrawable) background;
    shapeDrawable.getPaint().setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof GradientDrawable) {
    // cast to 'GradientDrawable'
    GradientDrawable gradientDrawable = (GradientDrawable) background;
    gradientDrawable.setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof ColorDrawable) {
    // alpha value may need to be set again after this call
    ColorDrawable colorDrawable = (ColorDrawable) background;
    colorDrawable.setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
}

Компактная версия:

Drawable background = imageView.getBackground();
if (background instanceof ShapeDrawable) {
    ((ShapeDrawable)background).getPaint().setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof GradientDrawable) {
    ((GradientDrawable)background).setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof ColorDrawable) {
    ((ColorDrawable)background).setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
}

Обратите внимание, что нулевая проверка не требуется.

Тем не менее, вы должны использовать mutate()на чертежах перед их изменением, если они используются в другом месте. (По умолчанию загружаемые из XML файлы рисования имеют одинаковое состояние.)


3
Спасибо за ответы. (+1). Мой код испытывает другие ошибки, поэтому его сложно протестировать. Но все же это может установить solidчасть формы. Как насчет strokeпорции?
— Кот Мунио

1
@TiGer Вы должны добавить @usernameсвой комментарий, чтобы убедиться, что пользователю отправлено уведомление. Кстати, вам нужно будет ShapeDrawableсоздать подкласс для того, чтобы установить часть обводки. Больше информации здесь: Ссылка . Посмотрите на комментарий, поскольку он упоминает проблему с принятым ответом.
— Викрам

3
android.graphics.drawable.GradientDrawable не может быть приведен к android.graphics.drawable.ShapeDrawable Приведение мне не удалось
— Джон

3
@John Если ImageView'sфон установлен на a GradientDrawable, getBackground()не вернет a ShapeDrawable. Вместо этого используйте GradientDrawable, возвращаемый: GradientDrawable gradientDrawable = (GradientDrawable)imageView.getBackground();.... gradientDrawable.setColors(new int[] { color1, color2 });.
— Викрам

2
Спасибо .. спас мой мир.
— sid_09

43

Делай так:

    ImageView imgIcon = findViewById(R.id.imgIcon);
    GradientDrawable backgroundGradient = (GradientDrawable)imgIcon.getBackground();
    backgroundGradient.setColor(getResources().getColor(R.color.yellow));

1
@ user3111850 Вы добавили android:backgroundсвой xml или даже setBackgroundв активность перед звонком getBackground()? Это должно работать, если вы сделали это.
— Ли И Хонг

41

В настоящее время более простым решением было бы использовать вашу форму в качестве фона, а затем программно изменить ее цвет с помощью:

view.background.setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_ATOP)

Смотрите PorterDuff.Mode для доступных опций.

ОБНОВЛЕНИЕ (API 29):

Вышеуказанный метод устарел начиная с API 29 и заменен следующим:

view.background.colorFilter = BlendModeColorFilter(Color.parseColor("#343434"), BlendMode.SRC_ATOP)

См. BlendMode для доступных опций.


4
Правильно одно: view.getBackground().setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_ATOP);на фоне могут быть границы или закругленные углы.
— Berkay Turancı

1
Хороший @ BerkayTurancı моя форма имела закругленные углы. Я мог бы пропустить getBackground()звонок. Мой imageview.src содержал форму, и я использовал: imageIndicator.setColorFilter(toggleColor, PorterDuff.Mode.SRC_ATOP);где toggleColorтолько int, который ранее сохранял результат от getColor ()
— Someone Somewhere

1
Наличие PorterDuff.Modeдля BlendModeColorFilterне компилируется, как это требуется BlendMode. Так что для API 29 так и должно быть view.background.colorFilter = BlendModeColorFilter(Color.parseColor("#343434"), BlendMode.SRC_ATOP).
— Оник

Хороший улов @ Оник. Я обновил ответ соответственно. Спасибо!
— Георгиос

14

Попробуй это:

 public void setGradientColors(int bottomColor, int topColor) {
 GradientDrawable gradient = new GradientDrawable(Orientation.BOTTOM_TOP, new int[]  
 {bottomColor, topColor});
 gradient.setShape(GradientDrawable.RECTANGLE);
 gradient.setCornerRadius(10.f);
 this.setBackgroundDrawable(gradient);
 }

подробнее проверить эту ссылку это

надеюсь помочь.


голосование за ссылку. Но это не ответ на мой вопрос.
— Кот Мунио

13

надеюсь, что это поможет кому-то с той же проблемой

GradientDrawable gd = (GradientDrawable) YourImageView.getBackground();
//To shange the solid color
gd.setColor(yourColor)

//To change the stroke color
int width_px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, youStrokeWidth, getResources().getDisplayMetrics());
gd.setStroke(width_px, yourColor);

1
Первоначально я не мог заставить это работать, я понял, что ваш Color должен быть представлен следующим образом:gd.setStroke(width_px, Color.parseColor("#FF5722"));
— pwnsauce

12

Расширяя ответ Викрама , если вы раскрашиваете динамические представления, такие как элементы представления переработчика и т. Д. ... Тогда вы, вероятно, захотите вызвать mutate (), прежде чем установить цвет. Если вы этого не сделаете, любые виды, которые имеют общий объект рисования (например, фон), также будут иметь свои измененные / цветные рисунки.

public static void setBackgroundColorAndRetainShape(final int color, final Drawable background) {

    if (background instanceof ShapeDrawable) {
        ((ShapeDrawable) background.mutate()).getPaint().setColor(color);
    } else if (background instanceof GradientDrawable) {
        ((GradientDrawable) background.mutate()).setColor(color);
    } else if (background instanceof ColorDrawable) {
        ((ColorDrawable) background.mutate()).setColor(color);
    }else{
        Log.w(TAG,"Not a valid background type");
    }

}

3
Нужны и дополнительные проверки и параметры: if (background instanceof LayerDrawable) { background = ((LayerDrawable) background.mutate()).getDrawable(indexIfLayerDrawable); } if (background instanceof ShapeDrawable)[...]для работы с фонами, которые используют <layer-list ... <item ....
— Джонни

11

На этот вопрос был дан ответ некоторое время назад, но его можно модернизировать, переписав его как функцию расширения kotlin.

fun Drawable.overrideColor(@ColorInt colorInt: Int) {
    when (this) {
        is GradientDrawable -> setColor(colorInt)
        is ShapeDrawable -> paint.color = colorInt
        is ColorDrawable -> color = colorInt
    }
}

7

это решение, которое работает для меня ... написал также в другом вопросе: Как динамически изменить цвет формы?

//get the image button by id
ImageButton myImg = (ImageButton) findViewById(R.id.some_id);

//get drawable from image button
GradientDrawable drawable = (GradientDrawable) myImg.getDrawable();

//set color as integer
//can use Color.parseColor(color) if color is a string
drawable.setColor(color)

4

Ничто не работает для меня, но когда я устанавливаю оттенок, он работает на Shape Drawable

 Drawable background = imageView.getBackground();
 background.setTint(getRandomColor())

требуется Android 5.0 API 21


3

Моя версия функции расширения Kotlin, основанная на ответах выше с Compat :

fun Drawable.overrideColor_Ext(context: Context, colorInt: Int) {
    val muted = this.mutate()
    when (muted) {
        is GradientDrawable -> muted.setColor(ContextCompat.getColor(context, colorInt))
        is ShapeDrawable -> muted.paint.setColor(ContextCompat.getColor(context, colorInt))
        is ColorDrawable -> muted.setColor(ContextCompat.getColor(context, colorInt))
        else -> Log.d("Tag", "Not a valid background type")
    }
}

1

Простой способ заполнить форму радиусом :

(view.getBackground()).setColorFilter(Color.parseColor("#FFDE03"), PorterDuff.Mode.SRC_IN);

1

Может быть, я слишком поздно. Но если вы используете Kotlin. Есть такой способ

var gd = layoutMain.background as GradientDrawable

 //gd.setCornerRadius(10)
  gd.setColor(ContextCompat.getColor(ctx , R.color.lightblue))
  gd.setStroke(1, ContextCompat.getColor(ctx , R.color.colorPrimary)) // (Strokewidth,colorId)

Наслаждаться....


0

Для тех, кто использует C # Xamarin, вот метод, основанный на фрагменте Викрама:

private void SetDrawableColor(Drawable drawable, Android.Graphics.Color color)
{
    switch (drawable)
    {
        case ShapeDrawable sd:
            sd.Paint.Color = color;
            break;
        case GradientDrawable gd:
            gd.SetColor(color);
            break;
        case ColorDrawable cd:
            cd.Color = color;
            break;
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.