用shape、selector自定义样式美化控件
2015-10-27 14:08
741 查看
我们经常看到很漂亮的控件,就像下边两个:
这样比较多样化的控件显示是很常见的,这是我现做的两个,且不论美观不美观,个人审美差异吧,我就喜欢绿色(不喜欢帽子
),你可能喜欢银色或是别的。闲话打住,这样的效果是怎么实现的呢?
有的人说“自定义控件”,不错,自定义控件能实现这样的效果,甚至更加美好,这个毋庸置疑!但是这里用自定义控件显然大材小用了——如果仅仅要求这些显示效果的话,根本用不到自定义控件这样的大工程——简简单单一个样式文件(shape或selector)就搞定了,下边我们来详细看看这两种文件。
;
我们创建shape文件(我的名字是myshape),注意*文件名中不能有大写字母,然后在Edittext中添加
。因为没有填充色,我们再给它加上填充色:
说明:android:radius总的声明每个角圆角半径,如果4个角一致,则一句话搞定
android:topLeftRadius
android:topRightRadius
android:bottomLeftRadius
android:bottomRightRadius分别是左上、右上、左下、右下角半径,4者任意其一出现则该角半径以它为准。
属性:
android:angle——Integer,渐变的角度。 0 代表从 left 到 right,90 代表bottom到 top。必须是45的倍数,默认为0,线性渐变有效;
android:centerX——Float,渐变中心的相对X坐标,在0到1.0之间;
android:centerY——Float,渐变中心的相对Y坐标,在0到1.0之间;
android:startColor——Color,开始的颜色值;
android:centerColor——Color,可选的颜色值,基于startColor和endColor之间;
android:endColor——Color, 结束的颜色;
android:gradientRadius——Float ,渐变的半径。只有在 android:type="radial"才使用;
android:startColor——Color,开始的颜色值;
android:type——Keyword,渐变的模式,下面值之一:
"linear" 线形渐变。这也是默认的模式
"radial" 辐射渐变。startColor即辐射中心的颜色
"sweep" 扫描线渐变。
android:useLevel——Boolean,如果在LevelListDrawable中使用,则为true。
以上各节点都是按需添加的!shape样式文件只能做到这样的静态显示,不能变动,那么我们上边那个有交互效果的按钮是怎么回事呢?这就要用到selector样式文件了。
行的注释 item 放开,那么下边的就永远无法触发了, 因为有 item 已经满足条件返回了。可以理解为代码中的 if 语句。
我们常用的state主要有android:state_enabled(是否可点击或可编辑)、android:state_pressed(是否按下)以及他们的组合。比如上边我们共使用了三种状态不可点击、可点击并且未按下、可点击已按下,对应的item中有对应状态显示的shape样式,这样在buttom中加上background="@drawable/xx"即可显示。
我们创建selector文件,(以Android Studio为例)选中drawable目录,右键new > Drawable resource file > 输入文件名如myselector(不能有大写),直接确定即可,然后将上边代码贴进去。看button的声明:
但是仔细看看,和上边给出的效果不一样啊——按钮背景变了,字颜色没有变,看着也缺乏灵动的感觉,下边我就来让字在点击的时候也改变颜色:
我们在shape中并没有发现关于textColor的相关设置,怎么办呢?但是Button中有textColor属性啊!我们可以照猫画虎再给textColor建一个selector文件来达到这个效果。
我们创建名为mytext的selector文件,发现在item子节点下有<color />标签,所以我们这样写:
在Button中加上
运行一下看效果。哦,NO!报错了——
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #3: <item> tag requires a 'android:color' attribute.
什么情况?item标签需要android:color属性?不是用<color />子标签吗?查了好多帖子什么的都没有说明,只有用法,我悲哀地改成这样:
好吧,先看结果吧——
效果达到了,可是我并不开心,因为试了一下selector文件中item的自标签<color />竟然没有效果,还有,上边这种写法在写android:color=""属性时没有代码提示,是我们强加上的吗,可我们是根据logcat报错加上的啊!?
(1)shape标签属性android:shape可用rectangle矩形(默认)、oval椭圆、line水平直线、ring圆环,我们只验证了矩形。
(2)shape样式中gradient子标签的属性android:userLevel干嘛用?
(3)selector样式的item下有很多标签(color、set、transition、animation-list……),我们只用了shape这一种,其他的都有什么作用呢?
(4)为什么我在给自加特效时item标签的andrid:color属性没有代码提示,这是我们强行加上的吗?有没有更好的写法吗?
暂时还没有想到上边这些问题的答案,如果有缘人对这几个问题有所了解,麻烦留言指导,程序猿大人在此谢谢了!
参考文章:
@LonelyRoamer Android
Drawable Resource学习(十二)、ShapeDrawable还是GradientDrawable?
这样比较多样化的控件显示是很常见的,这是我现做的两个,且不论美观不美观,个人审美差异吧,我就喜欢绿色(不喜欢帽子
),你可能喜欢银色或是别的。闲话打住,这样的效果是怎么实现的呢?
有的人说“自定义控件”,不错,自定义控件能实现这样的效果,甚至更加美好,这个毋庸置疑!但是这里用自定义控件显然大材小用了——如果仅仅要求这些显示效果的话,根本用不到自定义控件这样的大工程——简简单单一个样式文件(shape或selector)就搞定了,下边我们来详细看看这两种文件。
(一)shape样式文件的使用
我们先看shape样式文件,以下是shape文件的所有可用子节点:<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <!-- corners用于设置圆角半径 --> <corners ></corners> <!-- stroke用于设置边框宽度、颜色、边框虚线 --> <stroke ></stroke> <!-- solid用于设置内部区域填充色 --> <solid ></solid> <!-- gradient用于设置区域内渐变色 --> <gradient ></gradient> <!-- 设置大小 --> <size ></size> <!-- 设置内边距 --> <padding ></padding> </shape>下边我们看看shape根节点下每个子节点的功能,以EditText为例:
<EditText android:id="@+id/et" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="测试编辑框" android:textSize="30sp"/>默认的EditText的显示效果为
;
我们创建shape文件(我的名字是myshape),注意*文件名中不能有大写字母,然后在Edittext中添加
android:background="@drawable/myshape"
(1)在myshape.xml中添加corners子节点:
<!-- corners用于设置圆角半径 --> <corners android:radius="10dp" android:topLeftRadius="3dp" android:topRightRadius="10dp" android:bottomLeftRadius="20dp" android:bottomRightRadius="30dp" />但是显示不出来效果——
。因为没有填充色,我们再给它加上填充色:
(2)solid子节点:
<!-- solid用于设置内部区域填充色 --> <solid android:color="#FFFFFF" />再看效果(我错了,弄了这么个颜色,太不清楚了,是米白色背景,看不清楚的换个角度斜着看一下,就当活动活动颈部,咱这一行呵呵了):
说明:android:radius总的声明每个角圆角半径,如果4个角一致,则一句话搞定
android:topLeftRadius
android:topRightRadius
android:bottomLeftRadius
android:bottomRightRadius分别是左上、右上、左下、右下角半径,4者任意其一出现则该角半径以它为准。
(3)继续添加stroke子节点:
<!-- stroke用于设置边框宽度、颜色、边框虚线间隔长度、虚线中每段实线的长度 --> <stroke android:width="1dp" android:color="#F860Af" android:dashGap="4dp" android:dashWidth="12dp" />运行再看效果(角半径只用10dp那个):
(4)继续看padding子节点:
<!-- 设置内边距 --> <padding android:left="10dp"/>这里padding属性和控件的android:padding、android:paddingLeft、android:paddingTop、android:paddingRight、android:paddingBottom作用是一样的,这里只验证一下android:left就好,看效果:
(5)继续添加size子节点:
<!-- 设置大小 --> <size android:width="300dp" android:height="100dp"/>注意:这里指定的是本样式的大小,而不是控件的大小,所以很少用到这个节点属性,因为显然通过控件本身属性控制大小更简单,而且能使样式文件更多的重用!
(6)最后看比较麻烦的gradient子节点:
<!-- gradient用于设置区域内渐变色 --> <gradient android:startColor="@android:color/holo_red_light" android:centerColor="@android:color/white" android:endColor="@android:color/holo_green_light" android:type="radial" android:useLevel="false" android:centerX="0.5" android:centerY="0.5" android:gradientRadius="100dp"/>先看效果(此处没有使用size标签)
属性:
android:angle——Integer,渐变的角度。 0 代表从 left 到 right,90 代表bottom到 top。必须是45的倍数,默认为0,线性渐变有效;
android:centerX——Float,渐变中心的相对X坐标,在0到1.0之间;
android:centerY——Float,渐变中心的相对Y坐标,在0到1.0之间;
android:startColor——Color,开始的颜色值;
android:centerColor——Color,可选的颜色值,基于startColor和endColor之间;
android:endColor——Color, 结束的颜色;
android:gradientRadius——Float ,渐变的半径。只有在 android:type="radial"才使用;
android:startColor——Color,开始的颜色值;
android:type——Keyword,渐变的模式,下面值之一:
"linear" 线形渐变。这也是默认的模式
"radial" 辐射渐变。startColor即辐射中心的颜色
"sweep" 扫描线渐变。
android:useLevel——Boolean,如果在LevelListDrawable中使用,则为true。
以上各节点都是按需添加的!shape样式文件只能做到这样的静态显示,不能变动,那么我们上边那个有交互效果的按钮是怎么回事呢?这就要用到selector样式文件了。
(二)selector样式文件的使用
我们先看一个示例用的selector文件,我的叫myselect:<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!--<item > <shape> <corners android:radius="8dp"/> <solid android:color="@android:color/white"/> </shape> </item>--> <!-- 想在点击按钮是让按钮上的字也变色或者变字,怎么玩呢? --> <item android:state_enabled="false"> <shape> <corners android:radius="8dp"/> <solid android:color="#666666"/> <stroke android:color="#A46D3F" android:width="1dp"/> </shape> </item> <item android:state_enabled="true" android:state_pressed="false"> <shape> <corners android:radius="8dp"/> <solid android:color="@android:color/holo_green_light"/> <stroke android:color="#A46D3F" android:width="1dp"/> </shape> </item> <item android:state_enabled="true" android:state_pressed="true"> <shape> <corners android:radius="8dp"/> <stroke android:color="#A46D3F" android:width="1dp"/> <gradient android:startColor="@android:color/holo_red_light" android:endColor="@android:color/holo_green_light" android:useLevel="false" android:type="radial" android:centerX="0.5" android:centerY="0.5" android:gradientRadius="200dp"/> </shape> </item> </selector>大致浏览一下就会发现:selector样式中用到了shape样式。是的!selector样式文件其实就是一系列的shape样式的集合,相当于一个map,只是这个map的key不是字符串,而是根据各种state来进行匹配的。但是又有不同,因为这个匹配是有顺序的,相当于一串if-else语句,前边有匹配的就不再往后边继续找了,所以——Selector.xml中定义Item 顺序是有讲究的,条件限定越细致,则应该放到前面。比如这儿如果把3~8
行的注释 item 放开,那么下边的就永远无法触发了, 因为有 item 已经满足条件返回了。可以理解为代码中的 if 语句。
我们常用的state主要有android:state_enabled(是否可点击或可编辑)、android:state_pressed(是否按下)以及他们的组合。比如上边我们共使用了三种状态不可点击、可点击并且未按下、可点击已按下,对应的item中有对应状态显示的shape样式,这样在buttom中加上background="@drawable/xx"即可显示。
我们创建selector文件,(以Android Studio为例)选中drawable目录,右键new > Drawable resource file > 输入文件名如myselector(不能有大写),直接确定即可,然后将上边代码贴进去。看button的声明:
<Button android:id="@+id/btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:background="@drawable/myselector" android:text="Second" android:textSize="30sp"/>这样,按钮就有相应的效果了,基本效果就出来了。
但是仔细看看,和上边给出的效果不一样啊——按钮背景变了,字颜色没有变,看着也缺乏灵动的感觉,下边我就来让字在点击的时候也改变颜色:
我们在shape中并没有发现关于textColor的相关设置,怎么办呢?但是Button中有textColor属性啊!我们可以照猫画虎再给textColor建一个selector文件来达到这个效果。
我们创建名为mytext的selector文件,发现在item子节点下有<color />标签,所以我们这样写:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" > <color android:color="#A46D3F"/> </item> <item android:state_enabled="true" android:state_pressed="false"> <color android:color="#000000"/> </item> <item android:state_enabled="true" android:state_pressed="true" > <color android:color="@android:color/holo_green_light"/> </item> </selector>
在Button中加上
android:textColor="@drawable/mytext"
运行一下看效果。哦,NO!报错了——
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #3: <item> tag requires a 'android:color' attribute.
什么情况?item标签需要android:color属性?不是用<color />子标签吗?查了好多帖子什么的都没有说明,只有用法,我悲哀地改成这样:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:color="#A46D3F" /> <item android:state_enabled="true" android:state_pressed="false" android:color="#000000"> </item> <item android:state_enabled="true" android:state_pressed="true" android:color="@android:color/holo_green_light" /> </selector>
好吧,先看结果吧——
效果达到了,可是我并不开心,因为试了一下selector文件中item的自标签<color />竟然没有效果,还有,上边这种写法在写android:color=""属性时没有代码提示,是我们强加上的吗,可我们是根据logcat报错加上的啊!?
(3)未解决问题
好了,本文要说的用样式文件美化控件的话题就说完了,但是在文中遇到这些问题还需要我们继续学习和提高:(1)shape标签属性android:shape可用rectangle矩形(默认)、oval椭圆、line水平直线、ring圆环,我们只验证了矩形。
(2)shape样式中gradient子标签的属性android:userLevel干嘛用?
(3)selector样式的item下有很多标签(color、set、transition、animation-list……),我们只用了shape这一种,其他的都有什么作用呢?
(4)为什么我在给自加特效时item标签的andrid:color属性没有代码提示,这是我们强行加上的吗?有没有更好的写法吗?
暂时还没有想到上边这些问题的答案,如果有缘人对这几个问题有所了解,麻烦留言指导,程序猿大人在此谢谢了!
参考文章:
@LonelyRoamer Android
Drawable Resource学习(十二)、ShapeDrawable还是GradientDrawable?
相关文章推荐
- 如何使用CSS3的transition实现动画效果?
- 实现最小宽度的几种方法及CSS Expression[转]
- CSS动画animate.css动画效果全集中文解释
- 表单元素——checkbox样式美化
- 纯CSS代码实现各类气球泡泡对话框效果的代码解析
- ionic-CSS布局1
- CSS3判断手机横屏竖屏
- 设置IE文本模式,兼容css
- Emmet:HTML/CSS代码快速编写神器
- css中float left与float right的使用说明
- CSS的active伪类
- 纯CSS代码实现各类气球泡泡对话框效果
- CSS Border高级使用实例分享(三角等形状)
- CSS border三角、圆角图形生成技术详解
- 有利于SEO的DIV+CSS的命名规则小结
- 关于reset.css的疑问:为什么一定要重置浏览器样式?
- 织梦arclist 五条文章,每条显示的CSS样式不一样。实现方式如下。
- CSS hack
- CSS - cursor 使用
- style中的visibility样式特性