Android中自定义drawable states
2015-08-18 17:06
543 查看
drawable state系列文章
XML类型的drawable图片的解析处理过程
StateListDrawable使用详解
详解refreshDrawableList()的执行流程
Checkable Views
Android中自定义drawable states
===============================================
一个state list drawable在根据View的状态来显示不同的图片是非常有用的.例如,我们可以为一个按钮的背景定义一个按下状态和非按下状态的状态图片列表,按钮就会根据不同的状态改变图片.我们也可以通过自定义的图片状态列表使其变得更加的有用。
下面是一个邮件客户端,它分别标识了已读邮件和未读邮件。
上面的列表使用了一个ListView,每个列表项使用了一个RelativeLayout,在这个RelativeLayout中包含有一个ImageView和一个TextView,当显示每项的时候,你可以手工的转换两张图片,并且一次的设置背景颜色。但是通过定义一个自定义状态,你可以更加简单和方便的进行管理。
第一步:声明自定义的状态属性
自定义状态是声明在attrs.xml文件中,这个文件在应用的res/values目录下。
第二步:在图片状态列表中使用自定义的状态
在我们的例子中,有两个状态图片列表。
一个是用做背景改变的列表项:
一个是消息状态图标改变的列表项:
为了能够使用自定义的状态,需要使用应用的包名声明一个新的XML命名空间,并且使用新的命名空间作为自定义状态属性的前缀。
第三步:合入自定义的状态来更新View的drawable状态
每个View都提供了一些现存的可以使用的状态,例如CheckBox有选中状态,通过重写View.onCreateDrawableState() ,自定义View可以注入它自己的状态,然后我们就可以使用这个状态 。
在我们上面的例子中,包含有ImageView和TextView的RelativeLayout实现维持了一个未读状态,它可以设置和更新View的drawable状态,这样我们就可以看到已读和未读两种状态的邮件项。
我们知道,上面只是在MessageListItemView里面添加了自定义的状态,我们改变的只是MessageListItemView的状态,相应的触发了它背景颜色的改变。但是,ImageView包含在它的里面,MessageListItemView的状态是如何改变ImageView的状态的呢?
因为ImageView是我们自定义布局的一个子View,我们可以使用View.setDuplicateParentStateEnabled()告诉它去复制父布局的状态,这样父布局的状态就可以传递给包含了这个自定义状态的子布局中。
具体的代码如下:
View example application on Github
原文链接:
Custom drawable states in Android
XML类型的drawable图片的解析处理过程
StateListDrawable使用详解
详解refreshDrawableList()的执行流程
Checkable Views
Android中自定义drawable states
===============================================
一个state list drawable在根据View的状态来显示不同的图片是非常有用的.例如,我们可以为一个按钮的背景定义一个按下状态和非按下状态的状态图片列表,按钮就会根据不同的状态改变图片.我们也可以通过自定义的图片状态列表使其变得更加的有用。
下面是一个邮件客户端,它分别标识了已读邮件和未读邮件。
上面的列表使用了一个ListView,每个列表项使用了一个RelativeLayout,在这个RelativeLayout中包含有一个ImageView和一个TextView,当显示每项的时候,你可以手工的转换两张图片,并且一次的设置背景颜色。但是通过定义一个自定义状态,你可以更加简单和方便的进行管理。
第一步:声明自定义的状态属性
自定义状态是声明在attrs.xml文件中,这个文件在应用的res/values目录下。
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MessageState"> <attr name="state_message_unread" format="boolean"/> </declare-styleable> </resources>
第二步:在图片状态列表中使用自定义的状态
在我们的例子中,有两个状态图片列表。
一个是用做背景改变的列表项:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:example="http://schemas.android.com/apk/res/com.charlesharley.example.android.customdrawablestates" > <!-- We make the pressed and focused selector items transparent so the ListView's own selector states show through. --> <item android:state_pressed="true" android:drawable="@android:color/transparent" /> <item android:state_focused="true" android:drawable="@android:color/transparent" /> <item example:state_message_unread="true" android:drawable="@color/message_list_item_background_unread" /> </selector>
一个是消息状态图标改变的列表项:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:example="http://schemas.android.com/apk/res/com.charlesharley.example.android.customdrawablestates" android:constantSize="true" > <item example:state_message_unread="true" android:drawable="@drawable/message_read_status_unread" /> <item android:drawable="@drawable/message_read_status_read" /> </selector>
为了能够使用自定义的状态,需要使用应用的包名声明一个新的XML命名空间,并且使用新的命名空间作为自定义状态属性的前缀。
第三步:合入自定义的状态来更新View的drawable状态
每个View都提供了一些现存的可以使用的状态,例如CheckBox有选中状态,通过重写View.onCreateDrawableState() ,自定义View可以注入它自己的状态,然后我们就可以使用这个状态 。
在我们上面的例子中,包含有ImageView和TextView的RelativeLayout实现维持了一个未读状态,它可以设置和更新View的drawable状态,这样我们就可以看到已读和未读两种状态的邮件项。
public class MessageListItemView extends RelativeLayout { private static final int[] STATE_MESSAGE_UNREAD = {R.attr.state_message_unread}; private boolean messageUnread; // Constructors, view loading etc... @Override protected int[] onCreateDrawableState(int extraSpace) { // If the message is unread then we merge our custom message unread state into // the existing drawable state before returning it. if (messageUnread) { // We are going to add 1 extra state. final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); mergeDrawableStates(drawableState, STATE_MESSAGE_UNREAD); return drawableState; } else { return super.onCreateDrawableState(extraSpace); } } public void setMessageUnread(boolean messageUnread) { if (this.messageUnread != messageUnread) { this.messageUnread = messageUnread; // Refresh the drawable state so that it includes the message unread // state if required. refreshDrawableState(); } } }
我们知道,上面只是在MessageListItemView里面添加了自定义的状态,我们改变的只是MessageListItemView的状态,相应的触发了它背景颜色的改变。但是,ImageView包含在它的里面,MessageListItemView的状态是如何改变ImageView的状态的呢?
因为ImageView是我们自定义布局的一个子View,我们可以使用View.setDuplicateParentStateEnabled()告诉它去复制父布局的状态,这样父布局的状态就可以传递给包含了这个自定义状态的子布局中。
具体的代码如下:
View example application on Github
原文链接:
Custom drawable states in Android
相关文章推荐
- Android 系统属性SystemProperty分析
- 教你写一个Android可快速复用的小键盘输入控件
- Android 调用已安装市场,进行软件评分的功能实现
- Eclipse For Android 代码自动提示功能
- Android 软键盘盖住输入框的问题
- Android系统显示框架
- Android插件技术——(一)动态加载jar
- ADT(Android Developer Tools)中配置SVN
- 美团Android DEX自动拆包及动态加载简介
- 聊一聊 Android的TelephonyManage
- 待机异常篇
- Android分辨率适配设计开发指导书
- Android Fragment 真正的完全解析(上)
- Android动态改变布局,比如登陆弹出软键盘,登陆框上移(转载)
- android 获取屏幕大小
- Android(java)学习笔记173:BroadcastReceiver之 BroadcastReceiver静态注册(SD卡卸载或者安装案例)和 BroadcastReceiver动态注册注销
- Android Fragment 真正的完全解析(下)
- Android中使用Handler造成内存泄露
- 写一个android内置android程序
- android aidl 进程间通信需要注意msg的大小(android.os.TransactionTooLargeException)