当前位置:首页 > IT技术

notifyDataSetChanged和notifyDataSetInvalidated区别以及观察者模式的使用

时间:2019-07-09 10:40:00来源:IT技术作者:SEO探针小编阅读:74次「手机版」
 

notifydatasetinvalidated

notifydatasetChanged和notifydatasetinvalidated区别以及观察者模式的使用

看Observer和Observable的时候,爬了下listview的源码,研究了下Android中用到的观察者模式


两个方法

相同点

当改变Adapter数据后,调用两个方法都会刷新视图

不同点

notifyDataSetChanged会保存刷新前的状态,比如Listview滑动的位置;

notifyDataSetInvalidated会清空所有信息,重新布局,位置会到最上方;

源码

源码位于AdapterView中的内部类AdapterDataSetObserver (观察者)

class AdapterDataSetObserver extends DataSetObserver {

        private Parcelable minstanceState = null;

        @Override
        public void onChanged() {
            mDataChanged = true;
            mOldItemCount = mItemCount;
            mItemCount = getAdapter().getCount();

            // Detect the case where a cursor that was previously invalidated has
            // been repopulated with new data.
            if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
                    && mOldItemCount == 0 && mItemCount > 0) {
                AdapterView.this.onRestoreInstanceState(mInstanceState);
                mInstanceState = null;
            } else {
                rememberSyncState();
            }
            checkFocus();
            requestlayout();
        }

        @Override
        public void onInvalidated() {
            mDataChanged = true;

            if (AdapterView.this.getAdapter().hasStableIds()) {
                // Remember the current state for the case where our hosting activity is being
                // stopped and later restarted
                mInstanceState = AdapterView.this.onSaveInstanceState();
            }

            // Data is invalid so we should reset our state
            mOldItemCount = mItemCount;
            mItemCount = 0;
            mSelectedPosition = INVALID_POSITION;
            mSelectedRowId = INVALID_ROW_ID;
            mNextSelectedPosition = INVALID_POSITION;
            mNextSelectedRowId = INVALID_ROW_ID;
            mNeedSync = false;

            checkFocus();
            requestLayout();
        }

        public void clearSavedState() {
            mInstanceState = null;
        }
    }
源码说明
  • notifyDataSetChanged

    当调用notifyDataSetChanged,通过观察中会调用到onChanged,

    其中AdapterView.this.onRestoreInstanceState(mInstanceState);保存了当前Listview布局信息;

    最终调用父类 View 中`requestLayout()`重新布局;

  • 当调用notifyDataSetInvalidated , onInvalidated会被调用,布局信息被初始化,最终调用requestLayout,布局恢复初始状态。

使用场景

如果需要adapter丢弃用户操作后的信息,可以调用notifyDataSetInvalidated ,让listview初始化;反之则调用notifyDataSetChanged,让当前页面的位置,选中状态等信息保持不变;

当然最终使用场景可以分别调用两种方法实验。


观察者模式在Listview中的使用

Android 没有使用java提供的Observable ,而是使用Android源码中android.database.Observable<>

观察者模式的具体实现

  • 基类 Observable中 registerObserver unregisterObserver提供添加和删除观察者的方法;
  • 子类 DataSetObservable继承Observable,提供notifyChanged 通知mObserver.onChanged(),提供notifyInvalidated调用 mObserver.onInvalidated;
  • 观察者 DataSetObserver 中提供了 onChanged和onInvalidated两个未实现的方法;
  • Listview系列view的基类adapterView中提供了内部类AdapterDataSetObserver 继承DataSetObserver 实现了DataSetObserver的两个方法,用了操作ListView不同的状态;

具体实现

  • BaseAdapter中注册mDataSetObservable 被观察者,以及通知观察者
    DataSetObservable mDataSetObservable = new DataSetObservable();
    public void registerDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.registerObserver(observer);
    }
    public void unregisterDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.unregisterObserver(observer);
    }
    public void unregisterDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.unregisterObserver(observer);
    }
    public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }
  • AbsListView中注册和解绑
    @Override
    protected void onattachedToWindow() {
        mDataSetObserver = new AdapterDataSetObserver();
        mAdapter.registerDataSetObserver(mDataSetObserver);
    }
     @Override
    protected void onDetachedFromWindow() {
        mAdapter.unregisterDataSetObserver(mDataSetObserver);
        mDataSetObserver = null;
    }
  • 在加上文章最上面的源码,一套流程over

源码爬的很开心,pompip原创

相关阅读

SEO优化与SEM推广的区别

 SEO优化和SEM推广有什么不同?这两种方式哪种好些呢?SEO探针小编下面为您讲解一下:

品牌型网站与营销型网站的区别

现在很多企业在建设网站的时候不清楚网站应该做成什么类型的,网站的常规类型有产品展示型、品牌形象型、营销推广型。当然网站定位

网络推广和网络营销有什么区别

  网络推广和网络营销有什么区别?现在很多企业在网上发布产品和品牌信息,那么这种在网络上打广告的方式究竟是网络推广还是网络营

http与https有什么区别?

  http与https有什么区别?HTTP是超文本传输协议的缩写形式,而HTTPS表示安全的超文本传输协议。超文本传输协议是一组规则,必须遵循

域名和网址有什么区别?

 今天上海SEO优化给大家科普一下网站域名和网站网址的区别是什么?相信大家了解过网站域名,认为域名就是网址,其实不然,接下来小编为

分享到:

栏目导航

推荐阅读

热门阅读