Изменение цвета градиента фона на Android во время выполнения

Я экспериментирую с фоном Drawable и у меня до сих пор не было проблем.

Я сейчас пытаюсь изменить цвет градиента фона во время выполнения.

К сожалению, нет никакого API, чтобы изменить это во время выполнения, кажется. Даже не пытаясь mutate() drawable, как объяснено здесь: Drawable мутации

Пример XML выглядит следующим образом. Это работает, как и ожидалось.

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#330000FF"
        android:endColor="#110000FF"
        android:angle="90"/>
</shape>

К сожалению, я хочу список с различными цветами, и они должны быть программно изменены во время выполнения.

Есть ли другой способ создать этот градиентный фон во время выполнения? Возможно, даже не используя XML вообще?

5 ответов

Решение

Да! Нашел способ!

Пришлось забыть про XML, но вот как я это сделал:

В моей перегруженной функции getView() (ListAdapter) мне просто нужно было:

    int h = v.getHeight();
    ShapeDrawable mDrawable = new ShapeDrawable(new RectShape());
    mDrawable.getPaint().setShader(new LinearGradient(0, 0, 0, h, Color.parseColor("#330000FF"), Color.parseColor("#110000FF"), Shader.TileMode.REPEAT));
    v.setBackgroundDrawable(mDrawable);

И это дало мне тот же результат, что и фон XML выше. Теперь я могу программно установить цвет фона.

Я попытался использовать решение Phenome для Button view. Но как-то не получилось.

Я придумал кое-что еще: (Предоставлено: примеры Android API Demo)

package com.example.testApp;

import android.app.Activity;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.view.View;

public class TetApp extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        View v = findViewById(R.id.btn);
        v.setBackgroundDrawable( new DrawableGradient(new int[] { 0xff666666, 0xff111111, 0xffffffff }, 0).SetTransparency(10));

    }

    public class DrawableGradient extends GradientDrawable {
        DrawableGradient(int[] colors, int cornerRadius) {
            super(GradientDrawable.Orientation.TOP_BOTTOM, colors);

            try {
                this.setShape(GradientDrawable.RECTANGLE);
                this.setGradientType(GradientDrawable.LINEAR_GRADIENT);
                this.setCornerRadius(cornerRadius);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public DrawableGradient SetTransparency(int transparencyPercent) {
            this.setAlpha(255 - ((255 * transparencyPercent) / 100));

            return this;
        }
    }
}

Попробуйте мой код ниже:

 int[] colors = new int[2];
            colors[0] = getRandomColor();
            colors[1] = getRandomColor();


            GradientDrawable gd = new GradientDrawable(
                    GradientDrawable.Orientation.TOP_BOTTOM, colors);

            gd.setGradientType(GradientDrawable.RADIAL_GRADIENT);
            gd.setGradientRadius(300f);
            gd.setCornerRadius(0f);
            YourView.setBackground(gd);

Метод генерации случайного цвета:

public static int getRandomColor(){
    Random rnd = new Random();
    return Color.argb(255, rnd.nextInt(256), rnd.nextInt(56), rnd.nextInt(256));
}

Kotlin-версия ответа , предоставленного Phenome в качестве функции расширения:

      fun View.backgroundGradientDrawable(@ColorInt startColor: Int, @ColorInt endColor: Int): Unit {
    val h = this.height.toFloat()
    val shapeDrawable = ShapeDrawable(RectShape())
    shapeDrawable.paint.shader =
        LinearGradient(0f, 0f, 0f, h, startColor, endColor, Shader.TileMode.REPEAT)
    this.background = shapeDrawable
}

Гитхаб

В зависимости от ваших требований, использование списка состояний цвета вместо фиксированного цвета для startColor и endColor может делать то, что вы хотите.

Другие вопросы по тегам