4

I have created a seekbar with a custom LinearGradient drawable. However, I want to be able to change gradient ratio for each color, here I use 3 colors, they get equally distributed if positions is null. What I want, in fact, is to provide width or ratio to each color, for example change red ratio and set it only form 0% to 10% of seekBar width.

Here i want to, set 0% to 10% red, 10% - 80% yellow, and 80% to 100% red, and be able to change the width values for each color dynamically.

Is this possible, and if yes, can anyone guide me on how?

My code

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;
}

Image can be seen from current settings, its not as i described.

enter image description here

Amir Dora.
  • 2,831
  • 4
  • 40
  • 61

1 Answers1

2

This answer applies to using a LinearGradient as a Shader.

Change the LinearGradient colors to transition from a color to the same color by setting the colors array as follows:

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

Change the LinearGradient to define the regions for the colors as follows: See LinearGradient with positions

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);

This forces the Shader to transition from a color to the same color over a region creating a solid color.

enter image description here

The above will give an instant transition from one color to another. If you want a narrow transition (narrower than the default for LinearGradient), you can manipulate the colors and positions arrays as follows. In the following, we change the transition from the red to yellow.

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);

enter image description here

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • thank you @Cheticamp, i appreciate your help on this. I need to support api level less than 29. By custom drawable are you referring to xml drawables? I look into that also not sure if i will be able to update it dynamically. I will look in detail. thanks – Amir Dora. Oct 20 '20 at 12:32
  • yes i just checked in api level 28, it is working. one thing though, colors not blending in current version. Looking into to enable smooth mixing of color at edges and i will accept your answer. Thank you :) – Amir Dora. Oct 20 '20 at 12:49
  • 1
    @AmirDora.I don't understand your last comment. Are you saying that you do not want an instant transition from one color to another but want to have a narrow transition? – Cheticamp Oct 20 '20 at 12:56
  • yes exactly @Cheticamp, and sadly i am not able to find any documentation on it. – Amir Dora. Oct 20 '20 at 12:58