ListView之AutoUpdataAdapter(一)
来源:互联网 发布:vscode 编译提示 编辑:程序博客网 时间:2024/04/29 21:23
1、前言:
前面一篇文章写了GeneralAdapter,这个Adapter可以省去很多重复的代码,甚至可以用匿名内部类来写。前文链接:http://blog.csdn.net/xinxincement/article/details/51165284.但是上面封装的类,只能说写法比以前简洁了,并没有什么新的功能。我们在实际当中经常有这样的需求,就是当数据变化时,ListView可以自动进行更新,这样的功能怎么样来实现呢?
2、参考:
其实在ListView与Adapter这两个常用类中,我们知道,调用Adapter的notyfyDatasetChange()方法,Listview的界面就可以进行更新,它是怎么做到的呢?这里不得不说一下设计模式,这里用到的就是观察者模式,(或者监听模式也可以实现)。所谓观察者模式就是有一方是观察者,有一方是被观察者,观察者需在被观察者那里进行注册。我们最最常用的各种Listener实质上也是观察者模式的一种.下面我们先来看看Listener的实现方式(以View.view.onClickListener为例):
(1) Listener:
View.class源码5126至5131行,这段代码表明将我们传进去的inClickListener实例赋值给了View的OnClickListener这个成员变量;
public void setOnClickListener(@Nullable OnClickListener l) { if (!isClickable()) { setClickable(true); } getListenerInfo().mOnClickListener = l; }
ListenerInfo getListenerInfo() { if (mListenerInfo != null) { return mListenerInfo; } mListenerInfo = new ListenerInfo(); return mListenerInfo; }这里的getListenerInfo()返回的是ListenerInfo类的实例,而ListenerInfo是View类中的一个静态内部类,它有很多的成员变量,其中就包括mOnClickListener,而mListenerInfo又是View的一个成员变量 查看View.class源码我们发现,有两个方法调用了ListenerInfo.mOnClicklistener.onClick(this)这个方法,它们分别是:
public boolean callOnClick() { ListenerInfo li = mListenerInfo; if (li != null && li.mOnClickListener != null) { li.mOnClickListener.onClick(this); return true; } return false; }
public boolean performClick() { final boolean result; final ListenerInfo li = mListenerInfo; if (li != null && li.mOnClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); li.mOnClickListener.onClick(this); result = true; } else { result = false; } sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); return result; }
callOnClick()方法是提供给在程序中调用的,在内部没有直接使用,那么preFromClick()方法在内部有三处地方进行了调用,一个人是onKeyup(), 一个是辅助功能方法,再一个就是我们熟悉的onTouchEvent()了。源码我就不贴了,再贴就像是View源码分析了。
以上分析就是说明了一个问题,就是我们将一个Listener实例注册到了View类中,然后View类在适当的地方调用,这样就实现了我们的方法得以执行,这就是所谓的回调吧!
3、实现
学习了这么多,目的只有一个,那就是依照它的写法实现我们的目的,让我们的AutoUpdataAdapter实现自动更新,那么思路是什么呢?
第一步:我们也写一个接口(xxxListener);
第二步:在我们的数据源中写一个注册的方法;
第三步:当数据源变化时调用这个方法;
请看下面的代码:
- 定义一个接口:
public interface DatasetChangeListener {public void onDatasetChange();}
- 自定义数据源:
- 数据源变化时调用接口方法
public class ObserableList<E> extends ArrayList<E> { private static final long serialVersionUID = -9031831111939356165L;private DatasetChangeListener mListener;public void setDataChangeListener(DatasetChangeListener listener) {this.mListener = listener;}private void dataSetChange(){if(mListener != null){mListener.onDatasetChange();}}@Overridepublic boolean add(E object) {if(super.add(object)){dataSetChange();}return false;}@Overridepublic void add(int index, E object) {super.add(index, object);dataSetChange();}@Overridepublic boolean addAll(Collection<? extends E> collection) {if(super.addAll(collection)){dataSetChange();return true;};return false;}@Overridepublic boolean addAll(int index, Collection<? extends E> collection) {if(super.addAll(index, collection)){dataSetChange();return true;}return false;}@Overridepublic E remove(int index) {E e =super.remove(index);dataSetChange();return e;}@Overridepublic boolean remove(Object object) {if(super.remove(object)){dataSetChange();}return false;}@Overrideprotected void removeRange(int fromIndex, int toIndex) {super.removeRange(fromIndex, toIndex);dataSetChange();}@Overridepublic void clear() {super.clear();dataSetChange();}@Overridepublic E set(int index, E object) {E e = super.set(index, object);dataSetChange();return e;}}在这里,自定义了一个方法,为这个数据源类的成员变量DatasetChangeListener进行赋值(当然你也可以在构造中传进去),同时,每一个引起数据变化的方法都进行了复写,(当然也可以用JDK动态代理进行实现,不过这样要考虑不需要回调接口的方法的问题)调用接口中的方法onDatasetChange(),那么这个方法执行的是哪里的代码呢?
下面看AutoUpdataAdapter类:
public class AutoUpdataAdapter<T> extends GeneralAdapter<T> implements DatasetChangeListener {public AutoUpdataAdapter(int itemlayoutid, ObserableList<T> listdatas,IItemViewHolder iviewholder) {super(itemlayoutid, listdatas,iviewholder);listdatas.setDataChangeListener(this);}@Overridepublic void onDatasetChange() {notifyDataSetChanged();}}
对了,你没有看错,就是这么简单,因为我们复用了前面一篇文章中的GeneralAdapter,只要将数据换成我们自定义的ObserableList,实现DatasetChangeListener,并在构造中将自身注册到ObserableList中,就可以了!
到这里,只是实现了回调,那么这个方法要怎么写呢?对了,notifyDatasetChange();
其实这个方法本身的实现是一个观察者模式,具体实现看下面Oberser的分析。
最后,写一个Activity测试一下吧!
public class MainActivity extends Activity {private ListView listview ;private ObserableList<String> listdata;private char c = 97;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listview = (ListView) findViewById(R.id.main_listview);listdata = new ObserableList<String>();IItemViewHolder viewholder = new AutoUpdataViewHolder();AutoUpdataAdapter<String> adapter = new AutoUpdataAdapter<String>(R.layout.listview_item, listdata, viewholder);listview.setAdapter(adapter);System.out.println("listview:"+listview);System.out.println("adapter:"+adapter);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {int id = item.getItemId();if (id == R.id.action_add) {listdata.add(String.valueOf(c++));System.out.println("..add.."+c);return true;}if (id == R.id.action_remove) {listdata.remove(String.valueOf(--c));System.out.println("..remove.."+c);return true;}return super.onOptionsItemSelected(item);}}
测试的图片我就不贴,图片的使用还要多多学习,有测试成功的童鞋可以发一下.
写了这么多,Observer再写就太多了一点,下一篇再写吧!
本文资源下载:http://download.csdn.net/detail/xinxincement/9493717
0 0
- ListView之AutoUpdataAdapter(一)
- ListView之AutoupdataAdapter(二)
- Android 之 ListView (一)
- Android之Listview(一)
- Android入门之ListView (一)
- android控件之ListView(一)
- android 之 listview (一)
- android 之listview(一)
- Android入门之ListView (一)
- android listview系列之初步接触listview(一)
- Android入门第六篇之ListView (一)
- Android入门第六篇之ListView (一)
- Android入门第六篇之ListView (一)
- Android入门第六篇之ListView (一)
- Android入门第六篇之ListView (一)
- Android控件之ListView探究一
- Android控件之ListView探究一
- Android入门第六篇之ListView (一)
- 多进程多线程编程汇总(持续更新中)
- 古诗三重境界
- JSP语法
- 泛型的简单写法
- 用lufy引擎写的小游戏
- ListView之AutoUpdataAdapter(一)
- Cypher(神奇的WITH)
- python pil grab screen
- C++ primer plus第六版课后编程练习答案:6.1
- 非继承的 构造函数 与 析构函数
- leetcode 102.Binary Tree Level Order Traversal-数的层次遍历|递归|非递归实现
- C++ primer plus第六版课后编程练习答案:6.2
- Iterator简单剖析
- android 引导页面,根据viewpager设计,到最后一页时出现按钮进入到主页