7

我正在使用一个ViewPager选择题考试应用程序,它从更大的集合中随机选择三十个问题。我在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;
    }
}
4

2 回答 2

12

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

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

 android:configChanges="orientation|screenSize"

并在您的活动中覆盖 onConfigurationChanged(Configuration) ,例如

 @Override
 public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
 }
于 2013-01-14T18:15:28.743 回答
4

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

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

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

在 RadioGroups 上注册选项的最佳方式是什么?直接通过点击还是以其他方式?

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

于 2013-01-14T19:47:43.273 回答