如何在方向/配置更改后维护ListView片段状态?

时间:2015-01-30 23:03:59

标签: android android-fragments android-listview android-listfragment

我的应用程序中有一个ListView片段遇到了一些问题。

  1. 当我滚动到列表视图中的特定元素,然后旋转设备时,列表视图将重置为列表顶部。
  2. 当我在列表视图中进入多选模式时,然后旋转设备,重置所选列表项。
  3. 这是我的活动:

    public class TestActivity extends ActionBarActivity
    {
        protected static final String   FRAGMENT_TAG    = "TEST";
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_layout);
    
            Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
    
            FragmentManager fm = getFragmentManager();
            TestFragment f = (TestFragment)fm.findFragmentByTag(FRAGMENT_TAG);
    
            // If no fragment exists, then create a new one and add it!
            if (f == null)
            {
                fm.beginTransaction().add(R.id.fragment_holder, new TestFragment(), FRAGMENT_TAG)
                        .commit();
            }
        }
    }
    

    这是main_layout.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize" >
        </android.support.v7.widget.Toolbar>
    
        <FrameLayout
            android:id="@+id/fragment_holder"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </LinearLayout>
    

    这是我的TestFragment类,带有misc。内容已删除:

    public class TestFragment extends ListFragment
    {
        @Override
        public void onActivityCreated(Bundle savedInstanceState)
        {
            super.onActivityCreated(savedInstanceState);
        }
    
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState)
        {
            super.onViewCreated(view, savedInstanceState);
    
            // Sets the list up for multiple choice selection.
            ListView listView = getListView();
            listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
            listView.setMultiChoiceModeListener(this);
        }
    }
    

    我已经看过两次讨论。一个是说我应该在片段的setRetainInstance(true)方法中使用onCreate(Bundle savedInstanceState)。另一个说我应该使用onSaveInstanceState(Bundle bundle)onRestoreInstanceState(Bundle bundle)方法以某种方式跟踪内容。我想使用setRetainInstanceState(true)方法,但将其添加到项目中是这样的:

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setRetainInstanceState(true);
    }
    

    对我不起作用。我在这里做错了什么?

1 个答案:

答案 0 :(得分:3)

我建议您向Fragment添加Activity略有不同的方法。

TestActivity课程中,检查onCreate()方法中Bundle是否为空。如果savedInstanceState为null,则仅添加Fragment。这会阻止您的Activity在设备的方向发生变化时添加相同Fragment的其他实例。

public class TestActivity extends ActionBarActivity {

    protected static final String FRAGMENT_TAG = "TEST";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        if (savedInstanceState == null) { 

            getFragmentManager().beginTransaction()
                    .replace(R.id.fragment_holder, new TestFragment(), FRAGMENT_TAG)
                    .commit();
        }

    }

}

我建议不要将setRetainInstance(true)方法用于具有UI的Fragment。请查看StackOverflow讨论here,了解何时使用setRetainInstance(true)