Программно добавить тень к ShapeDrawable

Я пытаюсь сделать кнопки с разными градиентами программно. Я использую ShapeDrawable, и он работает как шарм.

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

Однако я хотел бы добавить тень к кнопке, не текст кнопки программно. Любая помощь будет оценена по достоинству.


person stevo.mit    schedule 26.12.2012    source источник


Ответы (2)


Однако я хотел бы добавить тень к кнопке, а не текст кнопки программно.

Я думаю, вам нужна тень за текущим рисунком, который вы создали. Если да, создайте LayerDrawable вместе с другим Drawable (помещенным первым), который будет действовать как тень:

    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);
person user    schedule 26.12.2012
comment
Благодарю вас! Оно работает. Есть ли способ сделать нижний слой тени немного размытым? (Я попробовал линейный градиент, но это выглядит странно...) - person stevo.mit; 27.12.2012
comment
@stevo.mit Я знаю, чего ты хочешь, но не могу придумать для этого ничего простого. Вы можете сделать свой собственный Drawable и в методе draw создать этот эффект или, что-то простое, создать маленькое изображение .png с желаемой тенью и создать BitmapDrawable с режимом плитки, установленным для повторения этого изображения png, а затем использовать этот BitmapDrawable в качестве теневого слоя. . - person user; 27.12.2012

Более чистый способ сделать это — использовать Paint.setShadowLayer, как в ответе Джека

person Eduardo Reis    schedule 16.06.2017
comment
Не похоже, что в вашей ссылке есть ответ Джека. - person Myoch; 25.11.2017
comment
что ты имеешь ввиду под программно? - person Arthur Melo; 12.11.2018
comment
@ Артур Мело. Использование кода вместо редактора макета. - person Eduardo Reis; 13.11.2018