• 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里返回想要的大小就行了。

  • 相关阅读:
    BZOJ3697: 采药人的路径
    解题:WC 2007 石头剪刀布
    解题:CQOI 2017 老C的方块
    解题:洛谷4314 CPU监控
    解题:CQOI 2017 老C的任务
    解题:CF1009 Dominant Indices
    解题:CF570D Tree Requests
    解题:APIO 2012 派遣
    解题:ZJOI 2015 幻想乡战略游戏
    解题:洛谷4178 Tree
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9253704.html
Copyright © 2020-2023  润新知