zoukankan      html  css  js  c++  java
  • Android深入研究Adapter重绘

            一直以来Adapter的使用都仅仅是流于表面,仅仅知道要实现几个抽象的方法,把Adapter设置给某种listView,就能够非常好的工作起来。所谓理解仅仅是建立在主观的猜想上面,认为应该是这样,对,ok,就这样,恩, 明确了。可是其实却没有正真的懂它。这能够说Android的设计模式真的做得非常好,无需了解实现就能够非常好的运用,只是总感觉没有深入的追究还是少了点什么。那就看看它的一些细节吧。尤其来看看我一直疑惑的为什么调用notifyDataSetChanged  notifyDataSetInvalidated 就能够重绘View。

            首先还是从我掌握的有限的线索開始,notifyDataSetChanged 方法是怎么实现的呢?

    依据经验发现,差点儿我们用到的Adapter都是继承自BaseAdapter,借助eclipse 的Type Hierarchy View 也能够确认确实是这么回事,ok,那看看它的实现:

        /**
         * Notifies the attached observers that the underlying data has been changed
         * and any View reflecting the data set should refresh itself.
         */
        public void notifyDataSetChanged() {
            mDataSetObservable.notifyChanged();
        }
    
        /**
         * Notifies the attached observers that the underlying data is no longer valid
         * or available. Once invoked this adapter is no longer valid and should
         * not report further data set changes.
         */
        public void notifyDataSetInvalidated() {
            mDataSetObservable.notifyInvalidated();
        }

    原来是个Observer的实现,这个倒是和我之前的猜想差点儿相同。

        public void notifyChanged() {
            synchronized(mObservers) {
                // since onChanged() is implemented by the app, it could do anything, including
                // removing itself from {@link mObservers} - and that could cause problems if
                // an iterator is used on the ArrayList {@link mObservers}.
                // to avoid such problems, just march thru the list in the reverse order.
                for (int i = mObservers.size() - 1; i >= 0; i--) {
                    mObservers.get(i).onChanged();
                }
            }
        }
    看来能够挂非常多个Observer,继续看看onChanged实现发现时个abstract的,怎么办,究竟是谁呢?看来要找个详细的实现。看看比較熟悉的ListView

    和比較熟悉的ListAdapter,在ListView的setAdapter里发现

                mDataSetObserver = new AdapterDataSetObserver();
                mAdapter.registerDataSetObserver(mDataSetObserver);

    AdapterDataSetObserver的实如今AdapterView:

     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;
            }
        }
    ok,原来是这样来更新的,明确了。

    总结起来看,全部的Adapter都是BaseAdapter的子类,全部的带Adapter的view都是AdapterView的子类。AbsListView也是AdapterView的子类。

    在View和Adapter关联的时候会把view的Oberver注冊到adapter上,所以在adapter数据变化的时候。view就能够通过observer了解到,从而能够及时更新。

    看来Adapter 模式的实现用了Oberver模式,隐隐约约还用到桥模式,不知道我的认识是不是正确呢。






  • 相关阅读:
    编程实现SQL Server备份和还原
    [推荐]asp.net string与color互换
    ASP.NET执行SQL超时的解决方案
    Starling 环形进度条实现
    [转]列举好游戏应具备的10个要素
    基于Starling的mask实现
    一直以来最头痛的问题:怎么样才能行之有效的解决游戏中后期枯燥的问题呢?求解
    [转]战棋系统的分析
    [转] java开源游戏
    设计模式(基础篇)软件设计七大设计原则(续一)
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4488358.html
Copyright © 2011-2022 走看看