在具有ViewPager的Fragment中保存ListView已选择的项目

3
我正在尝试制作一种测试应用程序,您可以通过向左或向右刷动来更改问题。因此,我有一个FragmentActivity、一个ViewPager和一个FragmentPagerAdapter。
每个新页面,FragmentPagerAdapter使用相同的布局实例化一个新的Fragment,布局上有一个ListView,总共有5个页面。然后,ArrayAdapter将ListView填充到4个CheckedTextViews,当用户选择一个时,背景会改变。
问题在于,当您从一个问题滑动到另一个问题时,所选项会丢失,并且当用户向后滑动到先前的问题时,该选项不再被选中。
虽然我是新手,但在直接从xml膨胀复选框时,它们的选择状态不会丢失。
以下是一些代码:
FragmentActivity onCreate():
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        //Getting the array of questions.
        res = getResources();
        questions = res.getStringArray(R.array.questions_1);

        // Create the adapter that will return a fragment for each of the five
        // questions of the app.
        mAdapter = new MyAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the FragmentPagerAdapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setOffscreenPageLimit(10);
        mViewPager.setAdapter(mAdapter);
    }

FragmentPagerAdapter:

    public class MyAdapter extends FragmentPagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);

    }

    @Override
    public int getCount() {
            //Number of pages
    return 5;
    }

    @Override
    public Fragment getItem(int position) {
        ArrayListFragment fragment = ArrayListFragment
                .newInstance(position);

        return fragment;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        Locale l = Locale.getDefault();

        return getString(R.string.title_section) + " " + (position + 1);

    }
}

片段类:

public static class ArrayListFragment extends Fragment {
            //Current Page number.
    int mNum;
    public static final String ARG_SECTION_NUMBER = "section_number";
    ListView list;

    /**
     * Create a new instance of ArrayListFragment, providing "num" as an
     * argument.
     */
    static ArrayListFragment newInstance(int num) {
        ArrayListFragment f = new ArrayListFragment();

        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putInt("num", num);
        f.setArguments(args);

        return f;
    }

    /**
     * When creating, retrieve this instance's number from its arguments.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mNum = getArguments() != null ? getArguments().getInt("num") : 1;

    }

    /**
     * The Fragment's UI is a textview showing a question and the ListView with               
             * the four possible answers.
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_pager_list, container,
                false);
        View tv = v.findViewById(R.id.text);
                    //Set the Question
        ((TextView) tv).setText(questions[mNum]);
        //Get que ListView and fill it.
        list = (ListView) v.findViewById(R.id.listView1);
        list.setAdapter(new ArrayAdapter<String>(getActivity(),
                R.layout.list_item, myStringArray));
                    //Select an item.
        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1,
                    int arg2, long arg3) {
                // TODO Auto-generated method stub
                arg1.setSelected(true);
            }

        });


        return v;
    }


}
2个回答

0

实际上,它不应该记住你的选择。一旦你离开页面,它可能会被销毁。默认情况下,ViewPager仅保存3个页面(当前页面、左侧页面和右侧页面)。但是,您可以在主机活动中保存用户选择。为此,您需要创建一个接口,其中包含一个函数public void onAnswerSelected(int questionId, int answerId),并在Activity中实现它。在片段中覆盖带有活动参数的onAttach函数。将其保存为类成员,您就有了回调到活动的方法。一旦用户选择答案,请调用callback.onAnswerSelected(questionId, answerId)。要恢复先前的状态,请在您的接口中添加另一个函数getSavedAnswer(int questionId)。当您在onActivityCreated()中时调用它。现在,您只需要在Activity中使用HashMap来保存答案即可。


谢谢您的回答。它节省了三页的空间,但是甚至不记得这三页中已经保存的选择。当我划到第二页时,第一页并没有被销毁,尽管如此它仍无法记住之前的选择。 - JMGA
实际上,在您的newInstance中,您总是创建ArrayListFragment的新实例,因此您总是会得到新片段。ViewPager将在任何情况下调用getItem。当您缓存特定数量的所有已创建片段时,在ViewPager适配器中保存片段列表。但是,您需要考虑配置更改情况,当ViewPager重新创建时。因此,保存数据在活动中的示例将更好,因为您可以覆盖onSaveInstance函数并保存所有答案。 - Androider

0

布局中带有复选框恢复状态是合理的。如果一个视图在布局中具有android:id属性,片段可以恢复其状态。但是您的listView不会恢复状态,因为它取决于适配器的实现方式。您必须手动执行此操作,例如:在片段的onSaveInstanceState中保存listView的选择状态,然后从savedInstanceState中获取您的选择,就像在Activity中一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接