android使用代码生成LayerDrawable的方法和注意事项

Posted carbs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android使用代码生成LayerDrawable的方法和注意事项相关的知识,希望对你有一定的参考价值。

为了有更好的UI体验,一般我们会把button、textview等控件的背景设置上阴影。传统的做法是美工提供一张具有阴影效果的nine patch图,然后将其在xml文件中添加到background属性。这种做法没有问题,不过缺乏灵活性。

图1.使用代码生成的具有“阴影”效果的控件

技术分享

android中,每一种在xml文件中定义的图片,均可以使用java代码生成,其中LayerDrawable对应的xml文件的根元素为<layer-list>。

首先我介绍一下使用xml文件生成“阴影”背景效果图片:

<?xml version= "1.0" encoding ="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item >
        <shape android:shape="rectangle" >
            <solid android:color="#ffbbbbbb" />

            <corners android:radius="2dp" />

        </shape>
    </item >

    <item
        android:bottom="1px"
        android:right="1px" >
        <shape android:shape="rectangle" >
            <solid android:color="#ffdddddd" />

            <corners android:radius="2dp" />

            <padding
                android:bottom="10dp"
                android:left="10dp"
                android:right="10dp"
                android:top="10dp" />
        </shape>
    </item >

</layer-list>

解析:

1.shape元素生成ShapeDrawable对象,不过需要注意的是,xml中虽然指明生成"rectangle"类型的对象,但如果想要在java中生成的rectangle具有圆角,那么java中对应的shape应该是RoundRectShape。
2.solid元素指明背景颜色,且paint的style为fill。
3.第二个元素android:bottom等代表的是LayerDrawable中第二个drawable相对于第一个drawable的inset,对应的java代码为:
layerDrawable.setLayerInset(1, 0, 0, 1, 1);
源码为:
 1 /** Specify modifiers to the bounds for the drawable[index].
 2         left += l
 3         top += t;
 4         right -= r;
 5         bottom -= b;
 6     */
 7     public void setLayerInset(int index, int l, int t, int r, int b) {
 8         ChildDrawable childDrawable = mLayerState.mChildren[index];
 9         childDrawable.mInsetL = l;
10         childDrawable.mInsetT = t;
11         childDrawable.mInsetR = r;
12         childDrawable.mInsetB = b;
13     }

可以看出setLayerInset()函数的作用就是将某层(层数从0开始计数)相对于上一层进行向里偏移。当然如果传入的数值为负数,就是向外偏移了,不过这时上层就遮挡住下层了,失去了使用layer的意义了。

4.padding的作用同样非常重要:

    (1)当在最上层使用padding时,它指明的是最上层的drawable边缘与内容之间的padding;

    (2)当在非最上层使用padding时,它指明当前层与上层之间的padding。

 

下面使用java代码生成LayerDrawable。

 

 1 private void setLayerBg(View view){
 2         
 3         int radius0 = 10;
 4         float[] outerR = new float[] { radius0, radius0, radius0, radius0, radius0, radius0, radius0, radius0 };
 5         RoundRectShape roundRectShape0 = new RoundRectShape(outerR, null, null);
 6         
 7         int radius1 = 10;
 8         float[] outerR1 = new float[] { radius1, radius1, radius1, radius1, radius1, radius1, radius1, radius1 };
 9         RoundRectShape roundRectShape1 = new RoundRectShape(outerR1, null, null);
10         
11         ShapeDrawable shapeDrawableBg = new ShapeDrawable();
12         
13         shapeDrawableBg.setPadding(0, 0, 0, 0);
14         shapeDrawableBg.setShape(roundRectShape0);
15 
16         shapeDrawableBg.getPaint().setStyle(Paint.Style.FILL);
17         shapeDrawableBg.getPaint().setColor(0xffbbbbbb);
18         
19         
20         ShapeDrawable shapeDrawableFg = new ShapeDrawable();
21         
22         shapeDrawableFg.setPadding(23, 23, 23, 23);
23         shapeDrawableFg.setShape(roundRectShape1);
24 
25         shapeDrawableFg.getPaint().setStyle(Paint.Style.FILL);
26         shapeDrawableFg.getPaint().setColor(0xffdddddd);
27         
28         Drawable[] layers = {shapeDrawableBg, shapeDrawableFg};
29         LayerDrawable layerDrawable = new LayerDrawable(layers);
30         layerDrawable.setLayerInset(1, 0, 0, 1, 1);
31         
32         view.setBackgroundDrawable(layerDrawable);
33         
34     }

注释我就不写了,具体的解释见上面的解析。

 

备注:

这里只是通过两幅颜色单一的drawable错位简单的生成“阴影效果”,后续可以通过shader等效果,生成逐渐淡出的“阴影”效果。



 

以上是关于android使用代码生成LayerDrawable的方法和注意事项的主要内容,如果未能解决你的问题,请参考以下文章

Android使用DOM生成和输出XML格式数据

Android 逆向代码调试器开发 ( 使用 NDK 中的 ndk-build + Android.mk 编译 Android 平台的代码调试器可执行应用 )

Android 逆向代码调试器开发 ( 使用 NDK 中的 ndk-build + Android.mk 编译 Android 平台的代码调试器可执行应用 )

android 怎么使用地图生成工具

如何在phonegap中使用android原生代码?

Android调试系列—使用android studio调试smali代码