【问题标题】:Fragment doesn't call onSaveInstanceState when swiping ViewPager?刷 ViewPager 时 Fragment 不调用 onSaveInstanceState?
【发布时间】:2011-12-07 21:55:49
【问题描述】:

我的 ViewPager 出现问题,我的 ListView 失去了滚动位置。

ListView 的状态可以通过以下方式轻松存储和恢复:

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
{
    View v = inflater.inflate(R.layout.frag_cool_things, container, false);

    AdvListView listView = (AdvListView) v.findViewById(R.id.lv0);
    listView.setOnItemClickListener( mOnListItemClicked );

    if (null != savedInstanceState)
    {
        listView.onRestoreListViewInstanceState(savedInstanceState.getParcelable("list_state"));
    }

    mListView = listView;

    return v;
}

@Override
public void onSaveInstanceState (Bundle outState) 
{
    super.onSaveInstanceState(outState);

    outState.putParcelable("list_state", mListView.onSaveListViewInstanceState());
}

但问题是,当片段被刷卡时,onDestroyView() 被调用但从不调用onSaveInstanceState (Bundle outState)

旋转屏幕等可以很好地恢复ListView 状态,但滑动我无法弄清楚如何正确恢复列表。

【问题讨论】:

    标签: android android-widget android-viewpager android-lifecycle


    【解决方案1】:

    2011 年 12 月 17 日更新:
    我实际上找到了保存片段内容的正确方法。您必须使用FragmentStatePagerAdapter。这个适配器正确地保存了片段的状态! :)

    旧:
    好吧,我找到了一种方法。如果您认为这是一个巨大的不,请分享您的意见! :P

    这是解决此问题的 FragmentBase 类:

    public abstract class FragmentBase extends Fragment
    {
        private boolean mInstanceAlreadySaved;
        private Bundle mSavedOutState;
    
        @Override
        public View onCreateView (LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) 
        {
            if (null == savedInstanceState && null != mSavedOutState) {
                savedInstanceState = mSavedOutState;
            }
    
            mInstanceAlreadySaved = false;
            return onCreateViewSafe(inflater, container, savedInstanceState);
        }
    
        @Override
        public void onSaveInstanceState (Bundle outState) 
        {
            super.onSaveInstanceState(outState);
            mInstanceAlreadySaved = true;
        }
    
        @Override
        public void onStop() 
        {
            if (!mInstanceAlreadySaved)
            {
                mSavedOutState = new Bundle();
                onSaveInstanceState( mSavedOutState );
            }
    
            super.onStop();
        }
    
        public abstract View onCreateViewSafe (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
    }
    

    【讨论】:

    • 我自己的临时解决方案是在 OnPause() 中将我的内容写入 SharedPreferences,然后在 OnCreateView(...) 中将它们取回。但是,这会迫使您访问附加活动以获取 Sharedpreferences (getActivity().getSharedPreferences(...)),并且当活动被拆除时,您可能还需要显式删除不需要的东西(取决于您是什么存储,ofc)。希望有人有更好的方法! :)
    • "FragmentPagerAdapter 将在您滑动列表时分离每个 Fragment,但将它们保留在内存中,以便在用户向后滑动时可以简单地重新附加它们。如果您有大量的 Fragment,FragmentStatePagerAdapter 是" (Android 开发者博客)
    • 建议的解决方案因此对于少量的 Fragment 来说不是最优的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多