zoukankan      html  css  js  c++  java
  • registerDataSetObserver:浅析Andorid ListView和Adapte

    最近由于遇到将内容分部绑定到ListView里的需求,追踪源码之后对ListView和Adapter有了点肤浅的认识,在此与大家分享。

    这里用到了观察者模式,在ListView的setAdapter里注册一个AdapterDataSetObserver观察者。

    1. public void setAdapter(ListAdapter adapter) {
    2. ........
    3. mDataSetObserver = new AdapterDataSetObserver();//AdapterDataSetObserver是ListView的基类AdapterView的内部类
    4. mAdapter.registerDataSetObserver(mDataSetObserver);//注册一个观察者
    5. .........
    6. requestLayout();//更新视图
    7. }

    ListAdapter是一接口,BaseAdapter继承了它

    1. public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
    2.     private final DataSetObservable mDataSetObservable = new DataSetObservable();
    3.  
    4.     public boolean hasStableIds() {
    5.         return false;
    6.     }
    7.      
    8.     public void registerDataSetObserver(DataSetObserver observer) {
    9.         mDataSetObservable.registerObserver(observer);
    10.     }
    11.  
    12.     public void unregisterDataSetObserver(DataSetObserver observer) {
    13.         mDataSetObservable.unregisterObserver(observer);
    14.     }
    15.      
    16.     /**
    17.      * Notifies the attached observers that the underlying data has been changed
    18.      * and any View reflecting the data set should refresh itself.
    19.      */
    20.     public void notifyDataSetChanged() {
    21.         mDataSetObservable.notifyChanged();
    22.     }
    23.  
    24.     /**
    25.      * Notifies the attached observers that the underlying data is no longer valid
    26.      * or available. Once invoked this adapter is no longer valid and should
    27.      * not report further data set changes.
    28.      */
    29.     public void notifyDataSetInvalidated() {
    30.         mDataSetObservable.notifyInvalidated();
    31.     }
    32.  
    33.     public boolean areAllItemsEnabled() {
    34.         return true;
    35.     }
    36.  
    37.     public boolean isEnabled(int position) {
    38.         return true;
    39.     }
    40.  
    41.     public View getDropDownView(int position, View convertView, ViewGroup parent) {
    42.         return getView(position, convertView, parent);
    43.     }
    44.  
    45.     public int getItemViewType(int position) {
    46.         return 0;
    47.     }
    48.  
    49.     public int getViewTypeCount() {
    50.         return 1;
    51.     }
    52.      
    53.     public boolean isEmpty() {
    54.         return getCount() == 0;
    55.     }
    56. }

    DataSetObservable定义如下:

    1. public class DataSetObservable extends Observable<DataSetObserver> {
    2.     public void notifyChanged() {//通知每个观察者数据已变化
    3.         synchronized(mObservers) {
    4.             for (DataSetObserver observer : mObservers) {
    5.                 observer.onChanged();
    6.             }
    7.         }
    8.     }
    9.  
    10.     public void notifyInvalidated() {
    11.         synchronized (mObservers) {
    12.             for (DataSetObserver observer : mObservers) {
    13.                 observer.onInvalidated();
    14.             }
    15.         }
    16.     }
    17. }

    ListView里注册的观察者是AdapterDataSetObserver对象,其定义如下:

    1. class AdapterDataSetObserver extends DataSetObserver {
    2.  
    3.         private Parcelable mInstanceState = null;
    4.  
    5.         @Override
    6.         public void onChanged() {
    7.             mDataChanged = true;
    8.             mOldItemCount = mItemCount;
    9.             mItemCount = getAdapter().getCount();//Adapter现有元素个数
    10.  
    11.             if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
    12.                     && mOldItemCount == 0 && mItemCount > 0) {
    13.                 AdapterView.this.onRestoreInstanceState(mInstanceState);
    14.                 mInstanceState = null;
    15.             } else {
    16.                 rememberSyncState();
    17.             }
    18.             checkFocus();
    19.             requestLayout();//更新视图
    20.         }
    21. .................
    22. }

    AdapterDataSetObserver里的具体实现我没弄清楚,但感觉是在这里更新了ListView显示的数据,ListView里是怎样更新的没弄清楚,希望哪位高手知道的告诉我。

    但是如果只在ListView里显示Adapter的部分数据,该怎么弄呢,可继承BaseAdapter,实现BaseAdapter里未实现的如下方法:

    getCount()、getItem(int position)、getItemId(int position)、getView(int position, View convertView, ViewGroup parent)。

    只需在getCount里返回想要的大小就行了。

  • 相关阅读:
    webpack中文网的错误&&未更新内容(webpack4)
    本地运行别人的vue项目;新建一个vue项目;打包并部署一个vue项目
    ajax/JSON
    弹性盒模型,FLEX
    opencv-python-学习笔记五(图像的基本操作)
    opencv-python-学习笔记四(创建滑动条)
    opencv-python-学习笔记三(鼠标事件)
    opencv-python-学习笔记二(利用opencv绘图)
    opencv-python-学习笔记一(图像的读取与写入)
    开发Koa 必须用的插件
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9253704.html
Copyright © 2011-2022 走看看