[原创]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 ><itemandroid:bottom="1px"android:right="1px" ><shape android:shape="rectangle" ><solid android:color="#ffdddddd" /><corners android:radius="2dp" /><paddingandroid: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     }

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

 

LayerDrawable和StateListDrawable相结合使用

当我们遇到可点击的控件时,需要给此控件自定义几个不同状态的background,比如按下效果、普通状态效果,这时就需要用到StateListDrawable。

采用LayerDrawable生成的图片具有的只是静态属性,当将不同状态的LayerDrawable添加到一个StateListDrawable中,这样控件不同状态时均选择是否具有阴影效果。

代码如下:

 1 @Override
 2     protected void onCreate(Bundle savedInstanceState) {
 3         super.onCreate(savedInstanceState);
 4         setContentView(R.layout.activity_main);
 5     
 6         text  = (TextView)this.findViewById(R.id.text);
 7         text.setBackgroundDrawable(getStateListDrawable());
 8         text.setOnClickListener(new View.OnClickListener() {
 9             
10             @Override
11             public void onClick(View v) {
12                 Toast.makeText(getApplicationContext(), "ttt", Toast.LENGTH_SHORT).show();
13             }
14         });
15    }
16 
17     private Drawable getStateListDrawable(){
18 
19         StateListDrawable stateListDrawable = new StateListDrawable();
20 
21         int[] stateHighlighted = new int[]{android.R.attr.state_pressed};
22         Drawable highlightedDrawable = getLayerDrawable(0xffcccccc);
23         stateListDrawable.addState(stateHighlighted, highlightedDrawable);
24 
25         int[] stateNormal = new int[]{};
26         Drawable normalDrawable = getLayerDrawable(0xffdddddd);
27         stateListDrawable.addState(stateNormal, normalDrawable);
28 
29         return stateListDrawable;
30     }
31     
32     private Drawable getLayerDrawable(int foregroundColor){
33         
34         int radius0 = 10;
35         float[] outerR = new float[] { radius0, radius0, radius0, radius0, radius0, radius0, radius0, radius0 };
36         RoundRectShape roundRectShape0 = new RoundRectShape(outerR, null, null);
37         
38         int radius1 = 10;
39         float[] outerR1 = new float[] { radius1, radius1, radius1, radius1, radius1, radius1, radius1, radius1 };
40         RoundRectShape roundRectShape1 = new RoundRectShape(outerR1, null, null);
41         
42         ShapeDrawable shapeDrawableBg = new ShapeDrawable();
43         shapeDrawableBg.setPadding(0, 0, 0, 0);
44         shapeDrawableBg.setShape(roundRectShape0);
45         shapeDrawableBg.getPaint().setStyle(Paint.Style.FILL);
46         shapeDrawableBg.getPaint().setColor(0xffbbbbbb);
47         
48         ShapeDrawable shapeDrawableFg = new ShapeDrawable();
49         shapeDrawableFg.setPadding(23, 23, 23, 23);
50         shapeDrawableFg.setShape(roundRectShape1);
51         shapeDrawableFg.getPaint().setStyle(Paint.Style.FILL);
52         shapeDrawableFg.getPaint().setColor(foregroundColor);
53         
54         Drawable[] layers = {shapeDrawableBg, shapeDrawableFg};
55         LayerDrawable layerDrawable = new LayerDrawable(layers);
56         layerDrawable.setLayerInset(1, 0, 0, 1, 1);
57         
58         return layerDrawable;
59     }

 

需要注意的是:当给View、TextView、ImageView、ViewGroup等类型的默认没有按下事件的控件添加StateListDrawable时,控件需要设置上click事件,否则按下效果不起作用

备注:

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

 

使用xml定义layer-list的示例:

 

使用layer-list定义的xml作为button的背景。其中:

Button1:
1.底部drawable没有设置padding
2.顶部drawable没有设置padding
3.顶部drawable设置inset为5px

        android:left="5px"android:top="5px"android:bottom="5px"android:right="5px"

button1背景的完整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="#ff00ff00" /><corners android:radius="3dp" /></shape></item ><itemandroid:left="5px"android:top="5px"android:bottom="5px"android:right="5px" ><shape android:shape="rectangle" ><solid android:color="#ffff0000" /><corners android:radius="3dp" /></shape></item ></layer-list>    

 

Button2:
1.底部drawable没有设置padding
2.顶部drawable设置inset均为5px

        android:left="5px"android:top="5px"android:bottom="5px"android:right="5px"

3.顶部drawable设置padding均为50dp

     <paddingandroid:bottom="50dp"android:left="50dp"android:right="50dp"android:top="50dp" />

 

button2背景的完整xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" ><!-- Z-Order 底部drawable --><item ><shape android:shape="rectangle" ><solid android:color="#ff00ff00" /><corners android:radius="3dp" /></shape></item ><!-- 顶部drawable --><itemandroid:left="5px"android:top="5px"android:bottom="5px"android:right="5px" ><shape android:shape="rectangle" ><solid android:color="#ffff0000" /><corners android:radius="3dp" /><paddingandroid:bottom="50dp"android:left="50dp"android:right="50dp"android:top="50dp" /></shape></item ></layer-list>

 

Button3:
1.底部drawable设置padding均为20dp
2.顶部drawable没有设置inset
3.顶部drawable设置padding均为50dp

 

    <paddingandroid:bottom="50dp"android:left="50dp"android:right="50dp"android:top="50dp" />

 

button3背景的完整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="#ff00ff00" /><corners android:radius="3dp" /><paddingandroid:bottom="20dp"android:left="20dp"android:right="20dp"android:top="20dp" /></shape></item><item><shape android:shape="rectangle" ><solid android:color="#ffff0000" /><corners android:radius="3dp" /><paddingandroid:bottom="50dp"android:left="50dp"android:right="50dp"android:top="50dp" /></shape></item></layer-list>    

 

 



 

转载于:https://www.cnblogs.com/carbs/p/5302908.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/491035.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Visual Studio 2013运行的结果一闪而过

在Visual Studio 2013中运行一个程序&#xff0c;发现输出结果的窗口DOS一闪而过&#xff0c;解决的办法是通过按CtrlF5键来运行程序即可

数字图像处理:四连通域与八连通域

四连通域与八连通域 1、所谓四连通区域或四邻域&#xff0c;是指对应像素位置的上、下、左、右&#xff0c;是紧邻的位置。共4个方向&#xff0c;所以称之为四连通区域&#xff0c;又叫四邻域。 2、所谓八连通区域或八邻域&#xff0c;是指对应位置的上、下、左、右、左上、右…

深度学习奠基人特伦斯:美国学界已经找到了解释人工智能“黑盒子”的方法...

&#xff08;图片来源&#xff1a;壹图网&#xff09;来源&#xff1a;今日头条经济观察网 记者 宋笛 “是的&#xff0c;目前美国数学家已经找到了解释深度学习黑盒子的方法&#xff0c;但是还没有发表&#xff0c;所以我不能透露更多。”7月25日 &#xff0c;美国“四院院士”…

this和static

1 【this】 2 指的是明确的标记本类的结构3 当前正在调用类中方法的对象&#xff0c;不是一个固定的4 java中以“{}”为界限。如果现在属性名称和参数名称重名&#xff0c;那么默认情况下&#xff0c;如果没有加任何的限制&#xff0c;指的是最近的“{}”内的变量名…

vs2013配置opencv2.4.9后出现找不到opencv_core249d.dll和opencv_highgui249d.dll问题

问题&#xff1a;vs2013配置opencv2.4.9后&#xff0c;运行程序&#xff0c;出现找不到opencv_core249d.dll和opencv_highgui249d.dll问题 解决办法&#xff1a;首先将opencv_core249d.dll&#xff1b;opencv_highgui249d.dll;opencv_imgproc249d.dll三个文件从“OpenCV的安装…

数字图像处理:图像的频域

数字图像处理&#xff1a;图像的频域 一、图像高频信号和低频信号的理解 1.1 图像中的低频信号和高频信号也叫做低频分量和高频分量。 1&#xff09;空间频率指的是图像中灰度值相对它的邻居点变化方式。如果一副图像中灰度从一边到另一边变化很小&#xff0c;那就说这副图像…

点击Cell中的按钮时,如何取所在的Cell

点击Cell中的按钮时&#xff0c;如何取所在的Cell&#xff1a; -(void)OnTouchBtnInCell:(UIButton *)btn { CGPoint point btn.center; point [table convertPoint:point fromView:btn.superview]; NSIndexPath* indexpath [table indexPathForRowAtPoint:point]; UITableV…

opencv2.4.9报错找不到opencv_video249d.dll

解决方法&#xff1a;将opencv_video249d.dll从“opencv安装路径\opencv\build\x86\vc12\bin”复制到“C:\Windows\SysWOW64”&#xff08;若是32位系统则复制到C:\Windows\System32&#xff09; opencv_video249d.dll中的249是版本号&#xff0c;代表OpenCV版本是2.4.9

Halcon算子学习:图像阈值分割-threshold、binary_threshold、dyn_threshold算子

Halcon算子学习&#xff1a;图像阈值分割算子前言1.threshold-全局固定阈值分割2.Binary Threshold-自动全局阈值分割3.dyn_threshold-局部动态阈值分割小结&#xff1a;4.var_threshold算子-均值和标准偏差局部阈值分割5.dual_threshold-双重阈值分割&#xff08;有符号图像的…

起底软银帝国:芯片、机器人、棒球队无所不投

来源&#xff1a;巴伦全球投资企鹅号划重点&#xff1a;孙正义喜欢将软银的投资组合比作银河系中的星星&#xff0c;称它们“将持续闪耀300年。”孙正义对阿里巴巴的投资可能是所有投资人做过的最好的投资之一。软银并非真正意义上的企业集团&#xff0c;其结构也不是封闭式基金…

visual studio如何中止正在运行的程序

如果是正在调试的程序&#xff0c;按shiftF5可以中止调试如果是正在运行的程序&#xff0c;按CtrlBreak(Pause) 可以中止运行

数字图像处理:数值图像的文件格式总结

文档下载&#xff1a; 数字图像文件的存储格式研究 1.前言 通过计算机处理的图像一般称为数字图像&#xff0c;它与传统照片不同&#xff0c;它可以通过某种软件被任意修改和编辑。但他又与传统照片有密切联系&#xff0c;因为好多图像信息大都由照片扫描而来&#xff0c;另…

OpenCV中VideoCapture判断isOpened()时总是返回false

将“OpenCV安装路径\opencv\build\x86\vc12\bin”下的opencv_ffmpeg249.dll文件拷贝到 exe 执行文件目录下&#xff08;工程文件下&#xff09; 注意两点&#xff1a; 这里opencv_ffmpeg249.dll中的249是版本号&#xff0c;代表安装的OpenCV版本是2.4.9&#xff0c;如果安装的…

南京大学潘天群教授:人类智能发展的宏大叙事

作者&#xff1a;南京大学哲学系教授&#xff0c;科学技术与社会研究所所长潘天群新拿到刚出版的《崛起的超级智能》一书&#xff0c;我一口气读完了。作者刘锋敏锐地观察到&#xff0c;今天的互联网已经不是个人电脑及智能手机等的简单连接&#xff0c;而是一个有生命的智能体…

[转]2016年Web前端面试题目汇总

记得去年 12月份刚来北京面试前端的时候 &#xff0c;下面的这问题大部分有涉及到...是不是要做题的都会出这些。。 HTML/CSS部分 1、什么是盒子模型&#xff1f; 在网页中&#xff0c;一个元素占有空间的大小由几个部分构成&#xff0c;其中包括元素的内容&#xff08;conte…

Halcon学习笔记:读取多张图片

1.第1种方法 遍历文件路径数组 path:E:/images1/ ImagePath:[] ImagePath[0]:a000.bmp ImagePath[1]:a001.bmp ImagePath[2]:a002.bmp ImagePath[3]:a003.bmp ImagePath[4]:a004.bmp ImagePath[5]:a005.bmp ImagePath[6]:a006.bmp ImagePath[7]:a007.bmp for i:0 to 7 by 1re…

Atitit.js this错误指向window的解决方案

Atitit.js this错误指向window的解决方案 1.1. 出现地点and解决之道1 1.2. call,apply和bind这三个方法2 1.2.1. Function.prototype.call2 1.3. 在函数内部出现的this&#xff0c;指什么要看这个this所在的函数的被调用方式。 不论这个this出现在什么样的函数中&#xff0c;层…

win10下VS2013+OpenCV2.4.9环境配置

参考来源https://blog.csdn.net/wsf09/article/details/78853823 一、安装Visual Studio2013 VS2013的安装可以参考软件安装管家公众号 二、配置OpenCV2.4.9 1、首先下载安装包 可以从OpenCV的官网下载 OpenCV2.4.9&#xff0c;但是会有点慢&#xff0c;中途可能还下载失败…

大脑简史(3)-大脑的结构

来源&#xff1a;人机与认知实验室前两篇文章&#xff0c;笔者和大家简短的介绍了一下大脑历史上的大事件和研究大脑的常用手段&#xff0c;这篇文章&#xff0c;想和大家分享一下&#xff1a;大脑的结构&#xff0c;也就是说&#xff1a;我们的大脑内究竟有什么。1967年&#…

Halcon算子学习:xyz_to_object_model_3d

xyz_to_object_model_3d (X, Y, Z : : : ObjectModel3D) 将3D点从图像转换为3D对象模型。 输入&#xff1a; X (input_object) 单通道图像→object (real) 用三维点的x坐标和三维点ROI区域。Y (input_object) 单通道图像→object (real) 图像与三维点的y坐标。Z (input_obje…