ViewPager PagerAdapter会在方向更改时重置

时间:2013-01-14 17:56:20

标签: android android-viewpager

我正在使用ViewPager作为多项选择考试应用程序,它会从更大的集合中随机选择30个问题。我在向PageAdapter提供页面的ViewPager中执行此操作。

问题在于,当发生方向更改时,不仅会重新加载寻呼机而且还会重新加载适配器 - 我知道如何保存当前寻呼机位置,但是当适配器重置时,它也会从集合中选择新问题。处理这个问题的正确方法是什么?

此外,附带问题 - 在RadioGroups上注册选项的最佳方式是什么?直接点击或以不同的方式?

我对Android应用程序开发还不熟悉。


的活动:

public class MyActivity extends SherlockActivity {
    ActionBar actionBar;
    ViewPager pager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        pager = new ViewPager(this);
        setContentView(pager);
        QuestionsAdapter adapter = new QuestionsAdapter(this);
        pager.setAdapter(adapter);

        int position = 0;
        if (savedInstanceState != null) {
            position = savedInstanceState.getInt("Q_NUMBER");
        }         
        pager.setCurrentItem(position);
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        int position = pager.getCurrentItem();
        savedInstanceState.putInt("Q_NUMBER", position);
    }
}

适配器:

class QuestionsAdapter extends PagerAdapter {
    Context context;
    QuestionsHelper dbQuestions;
    boolean exam;
    List<HashMap<String,Object>> examQuestions;

    public QuestionsAdapter(Context context, boolean exam) {
        this.context = context;
        this.examQuestions = GetQuestionsFromDB(30);
    }

    public Object instantiateItem(View collection, int position) {
        LayoutInflater inflater = (LayoutInflater) collection.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view;
        HashMap<String,Object> q;

        view = inflater.inflate(R.layout.exam_question_layout, null);
        q = getQuestion(position+1);

        ((TextView)view.findViewById(R.id.q_number)).setText(Integer.toString(position+1)+".");
        ((TextView)view.findViewById(R.id.q_question)).setText(q.get("question").toString());
        ((RadioButton)view.findViewById(R.id.q_answer_a)).setText(q.get("answer_a").toString());
        ((RadioButton)view.findViewById(R.id.q_answer_b)).setText(q.get("answer_b").toString());
        ((RadioButton)view.findViewById(R.id.q_answer_c)).setText(q.get("answer_c").toString());

        ((ViewPager)collection).addView(view, 0);
        return view;
    }
}

2 个答案:

答案 0 :(得分:12)

屏幕旋转将以新方向重新绘制整个屏幕,我们可以通过覆盖配置更改来阻止它。

在Android Manifest中的屏幕声明下添加android:configChanges =“orientation | screenSize”

 android:configChanges="orientation|screenSize"

并在您的活动中覆盖onConfigurationChanged(配置),如

 @Override
 public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
 }

答案 1 :(得分:4)

  

我知道如何保存当前的寻呼机位置但是当适配器时   重置后,它还会从集合中选择新问题。会是什么   处理这个的正确方法?

您的问题应该有id来唯一标识它们。我不确定你是如何从数据库中获取它们的,但是当发生这种情况时你需要存储它们的ID。也:

  • 您的适配器应该有一个long数组(或整数),其中包含30个值,表示当前所选批次问题的ID
  • 您需要在适配器中实现以下逻辑:如果前一点的长数组是null,那么假设它是一个干净的开始并获得一组新的30个问题。 如果long数组非null,那么我们正面临从配置更改中恢复,您需要使用这些ID来从数据库中获取正确的问题而不是随机批处理
  • Activity中,您将使用onSaveInstanceState()方法(savedInstanceState.putLongArray
  • 保存适配器的长数组
  • onCreate的{​​{1}}方法中,当您创建适配器时,您将检查Activity savedInstanceState以查看它是否为非null并且有长数组并在适配器上设置(因此它将知道要获得哪些问题)
  

在RadioGroups上注册选项的最佳方法是什么?   直接点击或以不同的方式?

您可以使用上述方法,或使用Bundle创建自定义类,就像在评论中已经向您推荐的一样。