android自定义更新,Android 完美解决自定义preference与ActivityGroup UI更新的问题

之前发过一篇有关于自定义preference 在ActivityGroup 的包容下出现UI不能更新的问题,当时还以为是Android 的一个BUG 现在想想真可笑 。其实是自己对机制的理解不够深刻,看来以后要多看看源码才行。

本篇讲述内容大致为如何自定义preference 开始到与ActivityGroup 互用下UI更新的解决方法。

首先从扩展preference开始:

类文件必须继承自Preference并实现构造函数,这里我一般实现两个构造函数分别如下(类名为:test):

publictest(Context context) {this(context,null);//TODO Auto-generated constructor stub}publictest(Context context, AttributeSet attrs) {

super(context, attrs);//TODO Auto-generated constructor stub}

这里第二个构造函数第二个参数为可以使用attrs 为我们自定义的preference 添加扩展的注册属性,比如我们如果希望为扩展的preference 添加一个数组引用,就可使用如下代码:

intresouceId=attrs.getAttributeResourceValue(null,"Entries",0);if(resouceId>0) {

mEntries=getContext().getResources().getTextArray(resouceId);

}

这里的mEntries 是头部声明的一个数组,我们可以在xml文件通过 Entries=数组索引得到一个数组。在这里不深入为大家示范了。

我们扩展preference 有时想让其UI更丰富更好看,这里我们可以通过引用一个layout 文件为其指定UI,可以通过实现如下两个回调函数:

@OverrideprotectedView onCreateView(ViewGroup parent) {//TODO Auto-generated method stubreturnLayoutInflater.from(getContext()).inflate(

R.layout.preference_screen, parent,false);

}

此回调函数与onBindView 一一对应,并优先执行于onBindView ,当创建完后将得到的VIEW返回出去给onBindView处理,如下代码:

@OverrideprotectedvoidonBindView(View view) {//TODO Auto-generated method stubsuper.onBindView(view);

canlendar=Calendar.getInstance();

layout=(RelativeLayout) view.findViewById(R.id.area);

title=(TextView) view.findViewById(R.id.title);

summary=(TextView) view.findViewById(R.id.summary);

layout.setOnClickListener(this);

title.setText(getTitle());

summary.setText(getPersistedString(canlendar.get(Calendar.YEAR)+"/"+(canlendar.get(Calendar.MONTH)+1)+"/"+canlendar.get(Calendar.DAY_OF_MONTH)));

}

Tip:onBindView 不是必须的,可以将onBindView 里的处理代码在onCreateView 回调函数一并完成然后返回给onBindView ,具体怎么写看自己的代码风格吧。我个人比较喜欢这种写法,比较明了。

下面我们来了解一下我扩展preference 比较常用到的几个方法:

Preference another)

与另外一个preference比较,如果相等则返回0,不相等则返回小于0的数字。

Object newValue)

如果你希望你扩展的Preference 可以支持当数值改变时候可以调用OnPreferenceChangeListener此监听方法,则必须调用此方法,查看该方法源码为:

protectedboolean callChangeListener(Object newValue) {returnmOnChangeListener==null?true: mOnChangeListener.onPreferenceChange(this, newValue);

}

源码简单不做过多介绍,只是实现一个接口。

protectedboolean getPersistedBoolean(boolean defaultReturnValue) {if(!shouldPersist()) {returndefaultReturnValue;

}returnmPreferenceManager.getSharedPreferences().getBoolean(mKey, defaultReturnValue);

}如果你有接触过sharePreference 相信一眼就能看出这里它为我们做了什么。

如上,获取一个String 数值

protectedboolean persistBoolean(boolean value) {if(shouldPersist()) {if(value==getPersistedBoolean(!value)) {//It's already there, so the same as persistingreturntrue;

}

SharedPreferences.Editor editor=mPreferenceManager.getEditor();

editor.putBoolean(mKey, value);

tryCommit(editor);returntrue;

}returnfalse;

}

都是sharePreference 的知识,这里不做过多介绍。其他的跟上面的都 一样,略过。

通过如上的一些设置,一个基本的扩展preference 就己经完成,下面来讲讲如果在ActivityGroup 里面让扩展的preference可以更新UI。之前 农民伯伯 探讨过,他建议我使用onContentChanged()方法,可以使UI更新 ,试了一下发现有些许问题,不过非常感谢农民伯伯。这个方法是全局刷新,则全部UI都刷新一次,但是这样不是很合理,我想了一下,那既然此方法可以更新UI那么一定可以行得通,我查看一下源码,下面把源码贴出来:

@OverridepublicvoidonContentChanged() {

super.onContentChanged();

postBindPreferences();

}/**

* Posts a message to bind the preferences to the list view.

* Binding late is preferred as any custom preference types created in

* {@link #onCreate(Bundle)} are able to have their views recycled.*/privatevoidpostBindPreferences() {if(mHandler.hasMessages(MSG_BIND_PREFERENCES))return;

mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();

}privatevoidbindPreferences() {

final PreferenceScreen preferenceScreen=getPreferenceScreen();if(preferenceScreen!=null) {

preferenceScreen.bind(getListView());

}

}

privatestaticfinalintMSG_BIND_PREFERENCES=0;privateHandler mHandler=newHandler() {

@OverridepublicvoidhandleMessage(Message msg) {switch(msg.what) {caseMSG_BIND_PREFERENCES:

bindPreferences();break;

}

}

};

原来,这里它是另开一条线程来更新UI,然后当值发生变化时为其发送消息,在消息队列里面处理UI,只不过它这里继承了listActivity 更新了一整个listView ,那么我们就将它提取出来,只更新我们想要的UI则可。OK,思路出来了,下面将我扩展的一个preference 的源码提供出来:

package com.yaomei.preference;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import android.app.Dialog;

import android.content.Context;

import android.content.DialogInterface;

import android.os.Handler;

import android.os.Message;

import android.preference.Preference;

import android.preference.PreferenceGroup;

import android.util.AttributeSet;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.view.View.OnClickListener;

import android.widget.AdapterView;

import android.widget.ListView;

import android.widget.RelativeLayout;

import android.widget.SimpleAdapter;

import android.widget.TextView;

import android.widget.AdapterView.OnItemClickListener;

import com.yaomei.set.R;publicclassPreferenceScreenExt extends PreferenceGroup implements

OnItemClickListener, DialogInterface.OnDismissListener {privateDialog dialog;privateTextView title, summary;privateRelativeLayout area;privateListView listView;

Listlist;privateList>listStr;privateCharSequence[] mEntries;privateString mValue;privateSimpleAdapter simple;privatestaticfinalintMSG_BIND_PREFERENCES=0;privateHandler mHandler=newHandler() {

@OverridepublicvoidhandleMessage(Message msg) {switch(msg.what) {caseMSG_BIND_PREFERENCES:

setValue(mValue);break;

}

}

};publicPreferenceScreenExt(Context context, AttributeSet attrs) {this(context, attrs, android.R.attr.preferenceScreenStyle);//TODO Auto-generated constructor stub}publicPreferenceScreenExt(Context context, AttributeSet attrs,intdefStyle) {

super(context, attrs, android.R.attr.preferenceScreenStyle);//TODO Auto-generated constructor stubintresouceId=attrs.getAttributeResourceValue(null,"Entries",0);if(resouceId>0) {

mEntries=getContext().getResources().getTextArray(resouceId);

}

}

@OverrideprotectedvoidonBindView(View view) {//TODO Auto-generated method stubarea=(RelativeLayout) view.findViewById(R.id.area);

title=(TextView) view.findViewById(R.id.title);

summary=(TextView) view.findViewById(R.id.summary);

title.setText(getTitle());

summary.setText(getPersistedString(getSummary().toString()));

area.setOnClickListener(newOnClickListener() {

@OverridepublicvoidonClick(View v) {//TODO Auto-generated method stubshowDialog();

}

});

}

@OverrideprotectedView onCreateView(ViewGroup parent) {//TODO Auto-generated method stuView view=LayoutInflater.from(getContext()).inflate(

R.layout.preference_screen, parent,false);returnview;

}publicvoidbindView(ListView listview) {intlength=mEntries.length;inti=0;

listStr=newArrayList>();for(i=0; i

HashMapmap=newHashMap();

map.put("keyname", mEntries[i].toString());

listStr.add(map);

}

simple=newSimpleAdapter(getContext(), listStr, R.layout.dialog_view,newString[] {"keyname"},newint[] { R.id.text });

listview.setAdapter(simple);

listview.setOnItemClickListener(this);

}publicvoidshowDialog() {

listView=newListView(getContext());

bindView(listView);

dialog=newDialog(getContext(), android.R.style.Theme_NoTitleBar);

dialog.setContentView(listView);

dialog.setOnDismissListener(this);

dialog.show();

}

@OverridepublicvoidonItemClick(AdapterView>parent, View view,intposition,longid) {//TODO Auto-generated method stubmValue=listStr.get(position).get("keyname").toString();

persistString(mValue);

callChangeListener(mValue);

dialog.dismiss();

}

@OverridepublicvoidonDismiss(DialogInterface dialog) {//TODO Auto-generated method stub}privateOnPreferenceChangeListener temp;publicinterfaceOnPreferenceChangeListener {publicboolean onPreferenceChange(Preference preference, Object newValue);

}publicvoidsetOnPreferenceChangeListener(

OnPreferenceChangeListener preference) {this.temp=preference;

}publicvoidsetValue(String value) {

summary.setText(value);

}publicboolean callChangeListener(Object newValue) {returntemp==null?true: temp.onPreferenceChange(this, newValue);

}publicvoidpostBindPreferences() {if(mHandler.hasMessages(MSG_BIND_PREFERENCES))return;

mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();

}

}

然后在preferenceActivity 界面在回调函数:onPreferenceChange调用postBindPreferences即可更新。

Tip:这里的onPreferenceChange  调用postBindPreferences 不是必须的,你同样可以在内部里面实现,通过执行某一操作发送消息也可。

好了,在这里我要感谢那几位朋友对我的帮助,提出了很多宝贵的意见。谢谢。

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

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

相关文章

vxlan 资料及其在 neutron中的应用

2019独角兽企业重金招聘Python工程师标准>>> VXLAN 是一个新兴的SDN 标准,它定义了一种新的 overlay 网络,它主要的创造者是 VMware, Cisco 和 Arista。它被设计来消除虚拟化网络世界中的 VLAN 数目的限制。VXLAN 本身是一个多播标准&#xf…

横流式冷却塔计算风量_研讨丨卓展标准高效制冷机房技术之影响冷却塔效率的几个因素...

集中制冷用空调系统中,单台冷却塔的冷却水量基本上都小于1,000m/h,且装有淋水填料的横流机械通风开式居多。本文将已横流开式冷却塔为对象,探讨影响其效率的几个因素。横流开式冷却塔示意图如下所示:横流开式冷却塔示意图 Fig 01说…

我是培训出来的我怕谁

引子: 江小峰是我带过的徒弟中跟我最久,也是最聪明的一个。 他一个高中生,没上过大学,高中毕业后在老家卖了三年电脑,天天给人装操作系统,有天他在网上看到某培训机构招生简介,一时冲动揣上三年血汗钱&…

android平台gallery2应用分析,Android5.1图库Gallery2代码分析数据加载流程

图片数据加载流程。Gallery---->GalleryActivity------>AlbumSetPage------->AlbumPage--------->PhotoPage相册集 照片集 某张图片1,AlbumSetPage.javaprivate void initializeData(Bundle data) {String mediaPath data…

python开课吧1980课程_开课吧的课程怎么样?

就那那些编程开发课来说。现在网络上充斥着大量的编程开发课程,什么python的,java的,c的,而且名字一个比一个夸张,21天精通c,7天熟练运用java,3天掌握python核心代码,这些课程标题简…

专业概念

1.JDBC: java数据库连接(JDBC)用于在java程序中实现数据库的操作功能,它提供了执行sql语句,访问各种数据库的方法,并为各种不同的数据库提供统一的操作接口,java.sql包中 包含了jdbc操作数据库的所有类 2.…

前端解决跨域问题的8种方案

2019独角兽企业重金招聘Python工程师标准>>> 1.同源策略如下: URL说明是否允许通信http://www.a.com/a.js http://www.a.com/b.js同一域名下允许http://www.a.com/lab/a.js http://www.a.com/script/b.js同一域名下不同文件夹允许http://www.a.com:8000/…

k歌的录音伴奏合成技术如何实现_K歌神器,用唱吧麦克风攀登天籁高峰

自从喜欢上了手机K歌,经常会上传一些自己的作品,起初无论音质如何都是乐在其中,可时间久了发现回放效果确实不如那榜单上的高手,究其原因想到了麦克风,网上一搜果然有各种K歌辅助工具,多番对比之下&#xf…

浅谈内存开辟问题和Block内存问题

我们知道,内存分为栈,堆,块。 栈中的内存由系统自己释放,堆是存对象初始化的地方,块是CPU与内存连接的缓冲器,运行速度比内存快,比CPU慢。 例如,我们NSMutableArray *array [NSMuta…

vue render函数_Vue原理解析(一):Vue到底是什么?

Vue,现在前端的当红炸子鸡,随着热度指数上升,实在是有必要从源码的角度,对它功能的实现原理一窥究竟。个人觉得看源码主要是看两样东西,从宏观上来说是它的设计思想和实现原理;微观上来说就是编程技巧&…

scrapy爬虫-setting.py

# Obey robots.txt rulesROBOTSTXT_OBEY False  不遵从网站的robots.txt法则 # See also autothrottle settings and docsDOWNLOAD_DELAY 3  每次下载延迟3秒,防止造成网站攻击 # Override the default request headers:DEFAULT_REQUEST_HEADERS { Accept:…

android点击左上角划出,使用Android中的Path和RectF在左上角右上角左下角绘制圆角...

有一个Path#addRoundRect()重载,它接受一个包含八个值的float数组,其中我们可以为四个角中的每一个指定x和y半径.这些值为[x,y]对,从左上角开始,顺时针绕其余部分.对于我们想要舍入的那些角,我们将该对的两个值都设置为半径值,并将它们保留为零,而不是那些.作为一个说明性示例,…

Nodejs微信开发

因为使用了Bot Framework开发了一个小功能,它目前支持了Skype\Teams\Slack等,但在国内来讲,微信还是一个比较流行的软件,所以需要接上微信 原来开发Bot的时候使用的是.Net开发的,这次我决定使用Nodejs开发一个简单的后…

性别有什么用_为啥不让男孩玩布娃娃?别让你的“性别偏见”,给孩子的人生设限...

在养育孩子的过程中,父母总是会犯许多错误,更是有一些错误会直接使孩子毁掉一生,而性别偏见正是很多家长都会去犯的错误,对男孩和女孩有着刻板印象,也正是因为这一点使孩子的潜力和天赋被压制。前几天我带着孩子去逛商…

android的时间代码怎么写,Android 日期和时间的使用实例详解

Android 日期和时间的使用日期和时间的使用;1:弹出框TimePickerDialog,DatePickerDialog2:组件TimePicker,DatePickerTimePickerDialog的使用:通过点击button显示图一,然后用户可以设置时间DatePickerDialog的使用只需…

andriod studio 查看项目依赖_Intellij IDEA 中如何查看maven项目中所有jar包的依赖关系图...

Maven 组件界面介绍如上图标注 1 所示,为常用的 Maven 工具栏,其中最常用的有:第一个按钮:Reimport All Maven Projects 表示根据 pom.xml 重新载入项目。一般单我们在 pom.xml 添加了依赖包或是插件的时候,发现标注 4…

Springboot 2.0.0单元测试

1. 引入spring-boot-starter-test包 1 <?xml version"1.0" encoding"UTF-8"?>2 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"3 xsi:schemaLocation"…

SPRING IN ACTION 第4版笔记-第二章-002-@ComponentScan、@Autowired的用法

一、ComponentScan 1. Configuration //说明此类是配置文件 ComponentScan //开启扫描&#xff0c;会扫描当前类的包及其子包 public class CDPlayerConfig { } 2. ComponentScan(basePackages{"soundsystem", "video"})//扫描多个包 public class CDP…

Kurento协议

2019独角兽企业重金招聘Python工程师标准>>> Kurento媒体服务器可以被两种外部Kurento客户端控制&#xff0c;如Java或JavaScript。这些客户端使用Kuernto协议来和KMS通信。Kurento 协议是基于WebSocket协议&#xff0c;并使用了JSON-RPC V2.0 消息来提交请求和发送…

升级php7_PhpStorm 2019.3 发布,全面支持 PHP 7.4

PhpStorm 2019.3 发布了&#xff0c;这个版本主要集中在性能和质量上&#xff0c;旨在提供一个更稳定、更快的 IDE。PhpStorm 2019.3 全面支持 PHP 7.4&#xff0c;还带来 PSR-12 代码样式&#xff0c;用于远程解释器的 WSL&#xff0c;MongoDB 支持&#xff0c;HTTP 客户端更新…