ListView

来源:互联网 发布:火车头采集本地数据 编辑:程序博客网 时间:2024/05/29 19:10

ListView的适配器模式和观察者模式

标签(空格分隔):Android


1.ListView.setAdapter()

    @Override    public void setAdapter(ListAdapter adapter) {        //Adapter 是ListView父类AbsListView的成员变量ListAdapter mAdapter;        if (mAdapter != null && mDataSetObserver != null) {           //mAdapter的取消注册方法条用的是ListAdapter->Adapter-BaseAdapter的方法            mAdapter.unregisterDataSetObserver(mDataSetObserver);        }        resetList();        mRecycler.clear();        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {            mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, adapter);        } else {            mAdapter = adapter;        }        mOldSelectedPosition = INVALID_POSITION;        mOldSelectedRowId = INVALID_ROW_ID;        // AbsListView#setAdapter will update choice mode states.        super.setAdapter(adapter);        if (mAdapter != null) {            mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();            mOldItemCount = mItemCount;            mItemCount = mAdapter.getCount();            checkFocus();            //注册观察者模式            //AdapterDataSetObserver mDataSetObserver也是父类成员,在这里它才是观察者            mDataSetObserver = new AdapterDataSetObserver();            mAdapter.registerDataSetObserver(mDataSetObserver);            mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());            int position;            if (mStackFromBottom) {                position = lookForSelectablePosition(mItemCount - 1, false);            } else {                position = lookForSelectablePosition(0, true);            }            setSelectedPositionInt(position);            setNextSelectedPositionInt(position);            if (mItemCount == 0) {                // Nothing selected                checkSelectionChanged();            }        } else {            mAreAllItemsSelectable = true;            checkFocus();            // Nothing selected            checkSelectionChanged();        }        requestLayout();    }

2.BaseAdapter

    /**看看BaseAdapter     * 观察者模式就是在这里实现的     */    public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {        //观察者集合        private final DataSetObservable mDataSetObservable = new DataSetObservable();        //注册  ListView中setAdapter()条用的就是这些方法        public void registerDataSetObserver(DataSetObserver observer) {            mDataSetObservable.registerObserver(observer);        }        //取消            public void unregisterDataSetObserver(DataSetObserver observer){            mDataSetObservable.unregisterObserver(observer);        }        /**         * 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(); //具体实现看下面        }        ...    }    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(); //条用了观察者的方法            }        }    }

3.DataSetObserver

    public abstract class DataSetObserver {    /**     * This method is called when the entire data set has changed,     * most likely through a call to {@link Cursor#requery()} on a {@link Cursor}.     */    public void onChanged() {        // Do nothing    }    /**     * This method is called when the entire data becomes invalid,     * most likely through a call to {@link Cursor#deactivate()} or {@link Cursor#close()} on a     * {@link Cursor}.     */    public void onInvalidated() {        // Do nothing    }}/**这个是AbsListView中的一个类,AdapterView<ListAdapter>.AdapterDataSetObserver还是继承了上面那个类,所以当跳用adapter.notifyChanged()就会调用AdapterDataSetObserver的onChanged()方法,他才是真正的观察者*/class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {        @Override        public void onChanged() {            super.onChanged();  //使用父类的方法            if (mFastScroll != null) {                mFastScroll.onSectionsChanged();            }        }        @Override        public void onInvalidated() {            super.onInvalidated();            if (mFastScroll != null) {                mFastScroll.onSectionsChanged();            }        }    }/**ListAdapter中的AdapterDataSetBoserver*/    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();        }        ...    }

4.适配器模式

在我们使用ListView的Adapter中我们会自己实现一个类继承BaseAdapter,这样我们会实现getView()方法,在ListView的父类中有一个成员变量ListAdapter,BaseAdapter是实现了ListAdapter的,我们通过ListView的setAdapter()方法把我们自己定义的getview()方法传递进去实现了想要的结果

原创粉丝点击