javaandroidmaterial-designandroid-seekbarandroid-graphics

change LinearGradient colors ratio dynamically for custom seekBar


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


Solution

  • 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