Search code examples
androidandroid-viewandroid-custom-viewshapes

View background with dynamic multi colors and corners


I am trying to make a view with dynamic percent tag to set different colors in view and with corners (as figure).

enter image description here

If only set multi colors is very easy to do that, just calculate percent with view's width and set color to finish that. But I have no idea how to do that with corner.

Is there any ideas?

Thanks a lot.

EDIT

I use ShapeDrawable solution and there is the result as below. I only update the color and percent tag.

What my question is : why the split line is askew?

enter image description here

UPDATE

There is succesw to get result, but this is not what I want..

enter image description here

I hope I can get clear split like below:

enter image description here


Solution

  • I think I achived what you expected. Unfortunately, such drawable cannot be made as .xml but can be done in code. Here is the template:

    ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
        @Override
        public Shader resize(int width, int height) {
            LinearGradient lg = new LinearGradient(0, 0, width, 0,
                        new int[]{
                                ContextCompat.getColor(getContext(), android.R.color.holo_green_light),
                                ContextCompat.getColor(getContext(), android.R.color.holo_green_light),
                                ContextCompat.getColor(getContext(), android.R.color.holo_orange_light),
                                ContextCompat.getColor(getContext(), android.R.color.holo_orange_light),
                                ContextCompat.getColor(getContext(), android.R.color.holo_red_light),
                                ContextCompat.getColor(getContext(), android.R.color.holo_red_light),
                                ContextCompat.getColor(getContext(), android.R.color.holo_purple),
                                ContextCompat.getColor(getContext(), android.R.color.holo_purple)},
                        new float[]{0, 0.60f, 0.60f, 0.80f, 0.80f, 0.85f, 0.85f, 1}, Shader.TileMode.REPEAT);
                return lg;
        }
    };
    PaintDrawable p = new PaintDrawable();
    p.setShape(new RectShape());
    p.setCornerRadius(40);
    p.setShaderFactory(sf);
    

    Look into couple of details above. When creating LinearGradient you have to pass an array of colors and their position inside gradient. In order to achieve very long green you have to double green color and pass positions 0 and 0.96f. Then add orange color one time. Be caferul, that the different between green and purple must be very low (but the must be a space for orange color).

    Then just set appropriate radius:

    p.setCornerRadius(40);
    

    This solution is scalable as colors and colors' positions can be dynamically changed.