ListView保存滑动状态

       场景:一个Tab中的一个子Activty里有listView
       a.如果在此Activty中启动其他应用,当返回时系统为我门保存了当前状态(应该也是调用了以下方法来保存)。

       b.如果是在其他子Activty中启动其他应用,当返回时ListView滑动状态就会丢失。


       View类有一个继承自AbsSavedState的BaseSavedState类,所有View的子类都会继承这个BaseSavedState类。当然包括ListView,TextView等等。以下代码即可实现场景b中保存ListView滑动状态:

1.写出以下方法

    /**
     * Used to keep track of the scroll state of the list.
     */
    private Parcelable mListState = null;
	private static final String LIST_STATE_KEY = "liststate";
    @Override
    protected void onSaveInstanceState(Bundle icicle) {
        super.onSaveInstanceState(icicle);
        // Save list state in the bundle so we can restore it after the QueryHandler has run
        if (mList != null) {
            icicle.putParcelable(LIST_STATE_KEY, mList.onSaveInstanceState());
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle icicle) {
        super.onRestoreInstanceState(icicle);
        // Retrieve list state. This will be applied after the QueryHandler has run
        mListState = icicle.getParcelable(LIST_STATE_KEY);
    }
2.在合适的地方调用(比如onCreate):

		if(mListState!=null){
            mList.onRestoreInstanceState(mListState);
            mListState = null;
		}

         在ListView中SavedState继承自BaseSavedStateListView中的实现如下

    static class SavedState extends BaseSavedState {
        SparseBooleanArray checkState;
        LongSparseArray<Boolean> checkIdState;

        /**
         * Constructor called from {@link ListView#onSaveInstanceState()}
         */
        SavedState(Parcelable superState, SparseBooleanArray checkState,
                LongSparseArray<Boolean> checkIdState) {
            super(superState);
            this.checkState = checkState;
            this.checkIdState = checkIdState;
        }

        /**
         * Constructor called from {@link #CREATOR}
         */
        private SavedState(Parcel in) {
            super(in);
            checkState = in.readSparseBooleanArray();
            long[] idState = in.createLongArray();

            if (idState.length > 0) {
                checkIdState = new LongSparseArray<Boolean>();
                checkIdState.setValues(idState, Boolean.TRUE);
            }
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeSparseBooleanArray(checkState);
            out.writeLongArray(checkIdState != null ? checkIdState.getKeys() : new long[0]);
        }

        @Override
        public String toString() {
            return "ListView.SavedState{"
                    + Integer.toHexString(System.identityHashCode(this))
                    + " checkState=" + checkState + "}";
        }

        public static final Parcelable.Creator<SavedState> CREATOR
                = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }

//以下实现状态的保存和回复
   @Override
    public Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        return new SavedState(superState, mCheckStates, mCheckedIdStates);
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedState) state;

        super.onRestoreInstanceState(ss.getSuperState());

        if (ss.checkState != null) {
           mCheckStates = ss.checkState;
        }

        if (ss.checkIdState != null) {
            mCheckedIdStates = ss.checkIdState;
        }
    }

          View中,BaseSaveState的实现如下:

    /**
     * Base class for derived classes that want to save and restore their own
     * state in {@link android.view.View#onSaveInstanceState()}.
     */
    public static class BaseSavedState extends AbsSavedState {
        /**
         * Constructor used when reading from a parcel. Reads the state of the superclass.
         *
         * @param source
         */
        public BaseSavedState(Parcel source) {
            super(source);
        }

        /**
         * Constructor called by derived classes when creating their SavedState objects
         *
         * @param superState The state of the superclass of this view
         */
        public BaseSavedState(Parcelable superState) {
            super(superState);
        }

        public static final Parcelable.Creator<BaseSavedState> CREATOR =
                new Parcelable.Creator<BaseSavedState>() {
            public BaseSavedState createFromParcel(Parcel in) {
                return new BaseSavedState(in);
            }

            public BaseSavedState[] newArray(int size) {
                return new BaseSavedState[size];
            }
        };
    }
            

         AbsSavedState类实现了Parcelable接口,具体实现如下:

/**
 * A {@link Parcelable} implementation that should be used by inheritance
 * hierarchies to ensure the state of all classes along the chain is saved.
 */
public abstract class AbsSavedState implements Parcelable {
    public static final AbsSavedState EMPTY_STATE = new AbsSavedState() {};

    private final Parcelable mSuperState;

    /**
     * Constructor used to make the EMPTY_STATE singleton
     */
    private AbsSavedState() {
        mSuperState = null;
    }

    /**
     * Constructor called by derived classes when creating their SavedState objects
     * 
     * @param superState The state of the superclass of this view
     */
    protected AbsSavedState(Parcelable superState) {
        if (superState == null) {
            throw new IllegalArgumentException("superState must not be null");
        }
        mSuperState = superState != EMPTY_STATE ? superState : null;
    }

    /**
     * Constructor used when reading from a parcel. Reads the state of the superclass.
     * 
     * @param source
     */
    protected AbsSavedState(Parcel source) {
        // FIXME need class loader
        Parcelable superState = source.readParcelable(null);
         
        mSuperState = superState != null ? superState : EMPTY_STATE;
    }

    final public Parcelable getSuperState() {
        return mSuperState;
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
         dest.writeParcelable(mSuperState, flags);
    }

    public static final Parcelable.Creator<AbsSavedState> CREATOR 
        = new Parcelable.Creator<AbsSavedState>() {
        
        public AbsSavedState createFromParcel(Parcel in) {
            Parcelable superState = in.readParcelable(null);
            if (superState != null) {
                throw new IllegalStateException("superState must be null");
            }
            return EMPTY_STATE;
        }

        public AbsSavedState[] newArray(int size) {
            return new AbsSavedState[size];
        }
    };
}




没有更多推荐了,返回首页