динамически изменять соотношение цветов LinearGradient для пользовательского seekBar

Я создал панель поиска с пользовательским рисунком LinearGradient. Однако я хочу иметь возможность изменять коэффициент градиента для каждого цвета, здесь я использую 3 цвета, они распределяются одинаково, если positions равно null. На самом деле я хочу предоставить ширину или соотношение для каждого цвета, например, изменить соотношение красного и установить его только в форме 0% до 10% от seekBar width.

Здесь я хочу установить от 0% до 10% красного, от 10% до 80% желтого и от 80% до 100% красного и иметь возможность динамически изменять значения ширины для каждого цвета.

Возможно ли это, и если да, то может ли кто-нибудь подсказать, как это сделать?

Мой код

private ShapeDrawable getSeekBarGradientDrawable(int mRectWidth, int mRectHeight) {
    int[] colors = new int[] { Color.RED, Color.YELLOW, getResources().getColor(R.color.primaryButton, null)};

DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels - (int) getResources().getDimension(R.dimen.margin_padding_size_medium);

    Shader shader = new LinearGradient(
            0,
            0,
            width,
            mRectHeight,
            colors, new float[] {0.1f,0.7f,0.2f},
            Shader.TileMode.CLAMP);

    ShapeDrawable shape = new ShapeDrawable(new RectShape());
    shape.getPaint().setShader(shader);
    return shape;
}

Изображение видно из текущих настроек, это не так, как я описал.

введите здесь описание изображения


person Amir Dora.    schedule 15.10.2020    source источник


Ответы (1)


Этот ответ относится к использованию LinearGradient в качестве Shader.

Измените цвета LinearGradient на переход от одного цвета к тому же цвету, установив массив colors следующим образом:

int[] colors = new int[]{Color.RED, Color.RED, Color.YELLOW, Color.YELLOW, Color.GREEN, Color.GREEN};

Измените LinearGradient, чтобы определить области для цветов следующим образом: см. LinearGradient с позициями

Shader shader = new LinearGradient(  
    0,  
    0,  
    width,  
    mRectHeight,  
    colors, new float[]{0f, 0.1f, 0.1f, 0.8f, 0.8f, 1.0f},  
    Shader.TileMode.CLAMP);

Это заставляет Shader переходить от цвета к тому же цвету в области, создавая сплошной цвет.

введите здесь описание изображения

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

int[] colors = new int[]{Color.RED, Color.RED, Color.YELLOW, Color.YELLOW, Color.YELLOW, Color.GREEN, Color.GREEN};
Shader shader = new LinearGradient(
        0,
        0,
        width,
        mRectHeight,
        colors, new float[]{0f, 0.1f, 0.15f, 0.15f, 0.8f, 0.8f, 1.0f},
        Shader.TileMode.CLAMP);

введите здесь описание изображения

person Cheticamp    schedule 20.10.2020
comment
спасибо @Cheticamp, я ценю вашу помощь в этом. Мне нужно поддерживать уровень API менее 29. Под пользовательским рисунком вы имеете в виду чертежи xml? Я изучаю это и не уверен, смогу ли я обновлять его динамически. посмотрю подробно. Благодарность - person Amir Dora.; 20.10.2020
comment
да, я только что проверил уровень API 28, он работает. одно но, цвета не смешиваются в текущей версии. Изучая возможность плавного смешивания цветов по краям, я приму ваш ответ. Спасибо :) - person Amir Dora.; 20.10.2020
comment
@AmirDora.Я не понимаю твой последний комментарий. Вы хотите сказать, что вам не нужен мгновенный переход от одного цвета к другому, а нужен узкий переход? - person Cheticamp; 20.10.2020
comment
да, именно @Cheticamp, и, к сожалению, я не могу найти по нему никакой документации. - person Amir Dora.; 20.10.2020