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等效果,生成逐渐淡出的“阴影”效果。

				
时间: 2024-11-03 21:25:16

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

Android模拟器设置网络代理方法

在服务器上启动模拟器的时候加了--http-proxy,但是不起作用.所以搜了下面的方法 四种方法: 一:将网络连接代理设置写入配置数据库 (适合启动模拟器无界面) 1.通过命令行或者通过双击emulatoer可执行文件,打开模拟器 2.在命令行执行adb shell 打开android的控制台 (确保环境变量设置正确,即已经把Android_SDK/tools 添加到了PATH(Linux)/path(Windows)) 3.执行 ls -l /data/data/com.android.pr

Android异步任务的使用方法

Android上面的很多操作是不能直接放在ui线程上面的.当ui线程被阻塞5秒以上的时候应用会出现未响应的对话框过.当此现象出现的时候会直接影响用户的用户体验的.所以我们需要通过方法对异步任务或者操作进行相关的处理.在这里罗列出集中相关的处理方法: 首先我们最先想到的应该是使用Thread+Handler实现非UI线程更新UI界面,即在线程执行的时候通过发送message来通过Handler来处理和更新ui. 另外一种方法就是通过异步任务:AsyncTask来进行数据的处理,通过继承AsyncT

Android获取LayoutInflater对象的方法总结

在写Android程序时,有时候会编写自定义的View,使用Inflater对象来将布局文件解析成一个View.本文主要目的是总结获取LayoutInflater对象的方法. 1.若能获取context对象,可以有以下几种方法: LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View child = inflater.inflate(R.la

调试 Android* x86 应用程序的方法以及要使用的工具

作者:Xiaodong Wang 1.简介 众所周知,Android* 开发人员头顶许多称呼:设计员.程序猿等,并且通常会不可避免地被称为故障检修工.代码中的错误无法避免,因此无论您是否一开始就造成错误,了解调试工具以及如何迅速而有效地跟踪并解决错误都很重要.鉴于此,如今的 Android 开发人员必须掌握有效的调试技巧.本文提供了 Android 应用程序调试工具的简单教学,用于帮助 Android SDK 以及相关工具的新手迅速入门,并在 Android x86 平台上更有效地解决故障. 2

MyEclipse 10 中安装Android ADT 22插件的方法

MyEclipse 10 中安装Android ADT 22插件的方法 下载ADT包:http://dl.google.com/android/ADT-22.0.0.zip 将ADT-22.0.0.zip文件放在指定的目录下,例如D:\Programs\Android,不解压. 打开MyEclipse,点击菜单Help >MyEclipse Configuration Center,如下图 在MyEclipse Configuration Center中,点击Software标签,再点击add

Android peferenceActivity 自定义标题简单方法

Android peferenceActivity 自定义标题简单方法 peferenceActivity 完全使用定义好的布局. 因此不能简单象其它好窗口进行自定,现在我们需要加 一个自定义标题,比如象其它窗口一样加一个统一topbar. 假设这个topbar的布局是 title.xml 一.标准自定义标题栏方法 Android 提供自定义标题栏方法 我们简单实现. @Override protected void onCreate(Bundle savedInstanceState) { f

[Android]蓝牙相关接口及方法

首先,要操作蓝牙,先要在AndroidManifest.xml里加入权限 <uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permissionandroid:name="android.permission.BLUETOOTH" /> 然后,看下api,Android所有关于蓝牙开发的类都在android.bluetooth包下,共有8个类

【转】Android开启网络调试的方法

方法是偶然看到的:Android 终端adbd服务需要开启5555号端口来建立于adb的连接,如果未开启5555端口,则不能通过网络调试 查看是否可以网络调试: # netstat Android adb 不能通过网络调试的解决方法 有5555端口开放,说明可以进行连接:> adb connect 192.168.0.202 如果netstat显示没有5555端口开放,则需要设置adbd参数,并重新启动adbd服务:# stop adbd # setprop service.adb.tcp.po

Android两种旋转Bitmap方法比较

方法1. 利用Bitmap.createBitmap Bitmap adjustPhotoRotation(Bitmap bm, final int orientationDegree) { Matrix m = new Matrix(); m.setRotate(orientationDegree, ( float ) bm.getWidth() / 2, ( float ) bm.getHeight() / 2); try { Bitmap bm1 = Bitmap.createBitmap