保存和恢复的ExpandableListActivity的展开/折叠状态状态、ExpandableListActivity

2023-09-04 05:07:15 作者:壞気丶辻足

我有一个ExpandableListActivity(使用SimpleCursorTreeAdapter),它启动另一个活动时,用户点击一个子元素上。当pressing后退按钮在新的活动的所有列表项再次崩溃。我如何保存ExpandableListActivity的展开状态,再次恢复它。

我已经尝试实现的onSaveInstanceState()和onRestoreInstanceState()这样的...

  @覆盖
保护无效的onSaveInstanceState(包outState){
    super.onSaveInstanceState(outState);
    Parcelable listState = getExpandableListView()的onSaveInstanceState()。
    outState.putParcelable(ListState,listState);
}


@覆盖
保护无效onRestoreInstanceState(包状态){
    super.onRestoreInstanceState(州);
    Parcelable listState = state.getParcelable(ListState);
    getExpandableListView()onRestoreInstanceState(listState)。
}
 

...但onRestoreInstanceState()获取从来没有所谓。我也试图恢复在OnCreate()方法中的状态,但它不叫,以及:

 如果(savedInstanceState!= NULL){
    Parcelable listState = savedInstanceState.getParcelable(ListState);
    getExpandableListView()onRestoreInstanceState(listState)。
}
 

解决方案

不幸的是,扩张状态总是复位时的焦点将丢失,当它再次获得焦点,但ONSTART()的onCreate()将不会调用。所以,我现在变通的做法是手动存储的所有展开的项目的ID和()再次扩大他们ONSTART。我实现ExpandableListActivity的子类重用的行为。

 公共类PersistentExpandableListActivity扩展ExpandableListActivity {
    专用长[] expandedIds;

    @覆盖
    保护无效的OnStart(){
        super.onStart();
        如果(this.expandedIds!= NULL){
            restoreExpandedState(expandedIds);
        }
    }

    @覆盖
    保护无效的onStop(){
        super.onStop();
        expandedIds = getExpandedIds();
    }

    @覆盖
    保护无效的onSaveInstanceState(包outState){
        super.onSaveInstanceState(outState);
        this.expandedIds = getExpandedIds();
        outState.putLongArray(ExpandedIds,this.expandedIds);
    }

    @覆盖
    保护无效onRestoreInstanceState(包状态){
        super.onRestoreInstanceState(州);
        长[] expandedIds = state.getLongArray(ExpandedIds);
        如果(expandedIds!= NULL){
            restoreExpandedState(expandedIds);
        }
    }

    专用长[] getExpandedIds(){
        ExpandableListView列表= getExpandableListView();
        ExpandableListAdapter适配器= getExpandableListAdapter();
        如果(适配器!= NULL){
            INT长度= adapter.getGroupCount();
            ArrayList的<龙> expandedIds =新的ArrayList<龙>();
            的for(int i = 0; I<长度;我++){
                如果(list.isGroupExpanded(i))的{
                    expandedIds.add(adapter.getGroupId(ⅰ));
                }
            }
            返回toLongArray(expandedIds);
        } 其他 {
            返回null;
        }
    }

    私人无效restoreExpandedState(长[] expandedIds){
        this.expandedIds = expandedIds;
        如果(expandedIds!= NULL){
            ExpandableListView列表= getExpandableListView();
            ExpandableListAdapter适配器= getExpandableListAdapter();
            如果(适配器!= NULL){
                的for(int i = 0; I< adapter.getGroupCount();我++){
                    长的id = adapter.getGroupId(ⅰ);
                    如果(inArray(expandedIds,内径))list.expandGroup(ⅰ);
                }
            }
        }
    }

    私有静态布尔inArray(长[]数组,长素){
        为(长L:数组){
            如果(L ==元){
                返回true;
            }
        }
        返回false;
    }

    私有静态长[] toLongArray(名单<龙>列表){
        长[] RET =新长[则为list.size()];
        INT I = 0;
        为(长E:名单)
            RET [我+ +] = e.longValue();
        返回RET;
    }
}
 
达人堂 乾坤大挪移 教你找回已删文件

也许有人有一个更好的解决方案,但。

I have an ExpandableListActivity (using a SimpleCursorTreeAdapter) which starts another activity when the user clicks on a child-element. When pressing the back-button in the new activity all the list-items are collapsed again. How do I save the expanded state of the ExpandableListActivity and restore it again.

I already tried to implemented onSaveInstanceState() and onRestoreInstanceState() like this...

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Parcelable listState = getExpandableListView().onSaveInstanceState();
    outState.putParcelable("ListState", listState);
}


@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);
    Parcelable listState = state.getParcelable("ListState");
    getExpandableListView().onRestoreInstanceState(listState);
}

...but onRestoreInstanceState() gets never called. I also tried to restore the state in the onCreate() method but it isn't called as well:

if (savedInstanceState != null) {
    Parcelable listState = savedInstanceState.getParcelable("ListState");
    getExpandableListView().onRestoreInstanceState(listState);
}

解决方案

Unfortunately the expanded state always resets whenever the focus is lost and onCreate() is not called when it gets the focus again but onStart(). So my workaround for now is to manually store the IDs of all expanded items and expand them in onStart() again. I implemented a subclass of ExpandableListActivity to reuse the behavior.

public class PersistentExpandableListActivity extends ExpandableListActivity {
    private long[] expandedIds;

    @Override
    protected void onStart() {
        super.onStart();
        if (this.expandedIds != null) {
            restoreExpandedState(expandedIds);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        expandedIds = getExpandedIds();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        this.expandedIds = getExpandedIds();
        outState.putLongArray("ExpandedIds", this.expandedIds);
    }

    @Override
    protected void onRestoreInstanceState(Bundle state) {
        super.onRestoreInstanceState(state);
        long[] expandedIds = state.getLongArray("ExpandedIds");
        if (expandedIds != null) {
            restoreExpandedState(expandedIds);
        }
    }

    private long[] getExpandedIds() {
        ExpandableListView list = getExpandableListView();
        ExpandableListAdapter adapter = getExpandableListAdapter();
        if (adapter != null) {
            int length = adapter.getGroupCount();
            ArrayList<Long> expandedIds = new ArrayList<Long>();
            for(int i=0; i < length; i++) {
                if(list.isGroupExpanded(i)) {
                    expandedIds.add(adapter.getGroupId(i));
                }
            }
            return toLongArray(expandedIds);
        } else {
            return null;
        }
    }

    private void restoreExpandedState(long[] expandedIds) {
        this.expandedIds = expandedIds;
        if (expandedIds != null) {
            ExpandableListView list = getExpandableListView();
            ExpandableListAdapter adapter = getExpandableListAdapter();
            if (adapter != null) {
                for (int i=0; i<adapter.getGroupCount(); i++) {
                    long id = adapter.getGroupId(i);
                    if (inArray(expandedIds, id)) list.expandGroup(i);
                }
            }
        }
    }

    private static boolean inArray(long[] array, long element) {
        for (long l : array) {
            if (l == element) {
                return true;
            }
        }
        return false;
    }

    private static long[] toLongArray(List<Long> list)  {
        long[] ret = new long[list.size()];
        int i = 0;
        for (Long e : list)  
            ret[i++] = e.longValue();
        return ret;
    }
}

Maybe someone has a better solution though.