6

I am trying to make buttons with different gradients programmatically. I use ShapeDrawable and it works like a charm.

RoundRectShape rs = new RoundRectShape(new float[] { 12f, 12f, 12f, 12f, 12f, 12f, 12f, 12f }, null, null);
ShapeDrawable sd = new ShapeDrawable(rs);
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {

    @Override
    public Shader resize(int width, int height) {
        LinearGradient lg = new LinearGradient(0, 0, 0, height,
                new int[] { 
                    Color.parseColor("#feccb1"), 
                    Color.parseColor("#f17432"), 
                    Color.parseColor("#e86320"),
                    Color.parseColor("#f96e22") },
                new float[] {
                    0, 0.50f, 0.50f, 1 },
                Shader.TileMode.REPEAT);
             return lg;
        }
    };
sd.setShaderFactory(sf);
myBtn.setBackgroundDrawable(sd);

However I would like to add a shadow to the button, not the button text programmatically. Any help would be appreciated.

stevo.mit
  • 4,681
  • 4
  • 37
  • 47

2 Answers2

8

However I would like to add a shadow to the button, not the button text programmatically.

I guess you want the shadow behind the current drawable you built. If yes then make a LayerDrawable along with another Drawable(placed first) that will act as the shadow:

    RoundRectShape rss = new RoundRectShape(new float[] { 12f, 12f, 12f,
            12f, 12f, 12f, 12f, 12f }, null, null);
    ShapeDrawable sds = new ShapeDrawable(rss);
    sds.setShaderFactory(new ShapeDrawable.ShaderFactory() {

        @Override
        public Shader resize(int width, int height) {
            LinearGradient lg = new LinearGradient(0, 0, 0, height,
                    new int[] { Color.parseColor("#e5e5e5"),
                            Color.parseColor("#e5e5e5"),
                            Color.parseColor("#e5e5e5"),
                            Color.parseColor("#e5e5e5") }, new float[] { 0,
                            0.50f, 0.50f, 1 }, Shader.TileMode.REPEAT);
            return lg;
        }
    });

    LayerDrawable ld = new LayerDrawable(new Drawable[] { sds, sd });
    ld.setLayerInset(0, 5, 5, 0, 0); // inset the shadow so it doesn't start right at the left/top
    ld.setLayerInset(1, 0, 0, 5, 5); // inset the top drawable so we can leave a bit of space for the shadow to use

    b.setBackgroundDrawable(ld);
user
  • 86,916
  • 18
  • 197
  • 190
  • Thank you! It works. Is there a way to make underlaying "shadow" layer bit blurry? (I tried linear gradient, but it looks weird...) – stevo.mit Dec 27 '12 at 10:24
  • 1
    @stevo.mit I know what you want but I can't think of something simple for that. You could make your own `Drawable` and in the `draw` method create that effect or, something simple, create a small `.png` image with the desired shadow and create a `BitmapDrawable` with tile mode set to repeat that png image and then use that `BitmapDrawable` as the shadow layer. – user Dec 27 '12 at 10:35
0

A more clean way to do it is using Paint.setShadowLayer as in Jack's answer

Eduardo Reis
  • 1,691
  • 1
  • 22
  • 45