3

I am trying to set the background of a view to have a gradient whose color is generated from the Palette api

The gradient will go from a solid and fade out but I want the solid portion to take up a majority of the background. Right now it starts solid and then gradually fades out over the view width, I want it to where it will start fading out from around the center of the view width.

Here is what I do

            Palette.from(resource!!.toBitmap()).generate {
                if (it != null) {
                    val paletteColor = it.getDarkVibrantColor("#000000".toColorInt())

                    val gradientDrawable = GradientDrawable(
                        GradientDrawable.Orientation.LEFT_RIGHT,
                        intArrayOf(colorWithAlpha(paletteColor, 0f), colorWithAlpha(paletteColor, 1.0f))
                    )
                    gradientDrawable.cornerRadius = 0f
                    _contentTextBackground.background = gradientDrawable
                }
            }

Is there a way to set the gradient to start further away from the end of the view?

tyczj
  • 71,600
  • 54
  • 194
  • 296
  • 1
    I'm not sure which way you want the fade, but if I'm understanding the rest of it correctly, you just want to add another solid color value in the middle of the array; e.g., `intArrayOf(colorWithAlpha(paletteColor, 0f), colorWithAlpha(paletteColor, 1.0f), colorWithAlpha(paletteColor, 1.0f))`. – Mike M. Jul 30 '21 at 21:48
  • 1
    Just to make sure we're on the same page, a simple demo to show the effect I mean, with the transparent end on the left, which I think is how it is in the given snippet: https://i.stack.imgur.com/54lA5.png. – Mike M. Jul 31 '21 at 18:00
  • @MikeM. if you want to put this as an answer I will accept since this is the route I went with and worked the best – tyczj Aug 03 '21 at 16:12
  • I'm good. Just a quick suggestion. Glad it helped. Please feel free to proceed as you see fit. Thank you, though. I appreciate the offer. Cheers! – Mike M. Aug 03 '21 at 19:13

6 Answers6

1

You can do this via XML to change centerX and centerY attributes of GradientDrawable. But sadly, with GradientDrawable, this is not possible programmatically as discussed on Google Issue Tracker.

Abdul Mateen
  • 1,418
  • 1
  • 14
  • 32
1

For APIs below 29, try using a ShapeDrawable with a LinearGradient Shader as a background. This will give you fine-level control over the transition of the colors.

For API 29+, GradientDrawable allows for similar fine-level control over color transitions with setColors().

private fun getBackgroundGradient(width: Int): Drawable {
    val colors = intArrayOf(Color.BLUE and 0x00FFFFFF, Color.BLUE, Color.BLUE)
    val offsets = floatArrayOf(0.0f, 0.7f, 1.0f)

    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // Oddly, there is no constructor that accepts the offsets.
        GradientDrawable().apply {
            orientation = GradientDrawable.Orientation.LEFT_RIGHT
            setColors(colors, offsets)
        }
    } else {
        val shader: Shader = LinearGradient(
            0f, 0f, width.toFloat(), 1f, colors, offsets, Shader.TileMode.CLAMP
        )
        val shape = ShapeDrawable(RectShape())
        shape.paint.shader = shader
        shape
    }
}

I used 0.7f as the "center" to make a better (IMO) color transition near the 50% mark, but that value could easily be 0.5f or any other value between 0f and 1.0f.

In the following image, the horizontal bar is the width of the screen and is just a View. The vertical red line splits the screen into two to mark the transition.

enter image description here

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
0

As stated by @Abdul Mateen you cannot change the attributes in Graient Drawable. This is only possible if you do it via XML. But there is a workaround:

You could theoretically split your background view in half. Then you have two views on which you could then change the color, based on the Palette Library. One view would then be the solid color and the other one would have to have the Gradient in the Background. If you configure that correctly, you should have a perfect gradient from the middle.

TIMBLOCKER
  • 328
  • 4
  • 15
0

Try extending GradientDrawable and set fades and colour as per you needs.

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

reference from this: https://stackoverflow.com/a/5241693/14964046

Yahya M
  • 392
  • 3
  • 13
0

Just add the solid color in array one more like below

val gradientDrawable = GradientDrawable(
    GradientDrawable.Orientation.LEFT_RIGHT,
    intArrayOf(colorWithAlpha(paletteColor, 0f), colorWithAlpha(paletteColor, 1.0f),  colorWithAlpha(paletteColor, 1.0f))
                    )

Its not elegant, but works :-D

0

What I ended up doing was what Mike suggested in the comments was to just add more of the solid color the the color array of the GradientDrawable

so it looked like this

val gradientDrawable = GradientDrawable(
                        GradientDrawable.Orientation.LEFT_RIGHT,
                        intArrayOf(colorWithAlpha(paletteColor, 0f), colorWithAlpha(paletteColor, 1.0f), colorWithAlpha(paletteColor, 1.0f), colorWithAlpha(paletteColor, 1.0f))
                    )
tyczj
  • 71,600
  • 54
  • 194
  • 296