• 技术文章 >Java >java教程

    Android适配器(Adapter)、观察者(Observer) 模式的代码分析(图)

    黄舟黄舟2017-03-11 11:51:02原创1802
    适配器(Adapter)详述://m.sbmmt.com/java-article-355851.html

    观察者(Observer)详述://m.sbmmt.com/java-article-356024.html

    AdapterView 体系


    AdapterView中会使用Adapter

    Adapter 体系


    BaseAdapter 实现了 SpinnerAdapter、ListAdapter

    这样的形式,就是 适配器模式的应用, 这里是采用的是 接口适配器

    观察者(Observer) 模式

    在Adapter中定义了注册和反注册DataSetObserver的方法

    public interface Adapter {
      
        void registerDataSetObserver(DataSetObserver observer);
    
        void unregisterDataSetObserver(DataSetObserver observer);
    
        ...
    }
    public abstract class DataSetObserver {
    
        public void onChanged() {
            // Do nothing
        }
    
        public void onInvalidated() {
            // Do nothing
        }
    }
    public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
        private final DataSetObservable mDataSetObservable = new DataSetObservable();
    
        public void registerDataSetObserver(DataSetObserver observer) {
            mDataSetObservable.registerObserver(observer);
        }
    
        public void unregisterDataSetObserver(DataSetObserver observer) {
            mDataSetObservable.unregisterObserver(observer);
        }
    
        public void notifyDataSetChanged() {
            mDataSetObservable.notifyChanged();
        }
    
        public void notifyDataSetInvalidated() {
            mDataSetObservable.notifyInvalidated();
        }
        ...
    }
    public class DataSetObservable extends Observable<DataSetObserver> {
    
        public void notifyChanged() {
            synchronized(mObservers) {
                for (int i = mObservers.size() - 1; i >= 0; i--) {
                    mObservers.get(i).onChanged();
                }
            }
        }
    
        public void notifyInvalidated() {
            synchronized (mObservers) {
                for (int i = mObservers.size() - 1; i >= 0; i--) {
                    mObservers.get(i).onInvalidated();
                }
            }
        }
    }
    public abstract class Observable<T> {
    
        protected final ArrayList<T> mObservers = new ArrayList<T>();
    
        public void registerObserver(T observer) {
            if (observer == null) {
                throw new IllegalArgumentException("The observer is null.");
            }
            synchronized(mObservers) {
                if (mObservers.contains(observer)) {
                    throw new IllegalStateException("Observer " + observer + " is already registered.");
                }
                mObservers.add(observer);
            }
        }
    
        public void unregisterObserver(T observer) {
            if (observer == null) {
                throw new IllegalArgumentException("The observer is null.");
            }
            synchronized(mObservers) {
                int index = mObservers.indexOf(observer);
                if (index == -1) {
                    throw new IllegalStateException("Observer " + observer + " was not registered.");
                }
                mObservers.remove(index);
            }
        }
    
        public void unregisterAll() {
            synchronized(mObservers) {
                mObservers.clear();
            }
        }
    }

    DataSetObserver 观察者(观察数据集:发生变化onChanged、无效onInvalidated)

    Observable 处理观察者(添加、移除、注册、反注册)

    DataSetObservable extends Observable<DataSetObserver> 添加了通知数据改变和无效的 两个方法

    在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;
            }
        }

    自定义了AdapterDataSetObserver,在两个实现方法中都调用了requestLayout(),重新设置layout

    整个观察数据变化导致界面改变的流程:
    1. 在AdapterView体系中 自定义 AdapterDataSetObserver,并注册(即添加observer到observable)。

    2. 在调用adapter.notifyDataSetChanged()后,内部执行observable的notifyChanged(),

    将执行每一个observer的onChanged(),也就达到了更新界面的效果。

    notifyDataSetInvalidated同理

    以上就是Android适配器(Adapter)、观察者(Observer) 模式的代码分析(图)的详细内容,更多请关注php中文网其它相关文章!

    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    上一篇:详细介绍Android建造者(Builder)模式的案例 下一篇:详细介绍Android使用Java8新特性之Lambda expression的示例代码
    大前端线上培训班

    相关文章推荐

    • 理解java8中java.util.function.*pojo反射新方法(附代码)• 浅析安卓app和微信授权登录及分享完整对接(代码分享)• 教你一招搞定时序数据库在Spring Boot中的使用• 一招教你使用java快速创建Map(代码分享)• PlayFramework 完整实现一个APP(十一)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网