【发布时间】:2017-04-14 00:11:53
【问题描述】:
我想做一个测验应用程序。到目前为止,我有 3 个活动 - 家庭、测验、得分。由于测验活动包含多个等效视图(图像标题、问题和 4 个答案按钮),我做了一些阅读并决定
ViewPager 和 FragmentStatePagerAdapter 显示就可以了。所以我制作了一个xml 模板并膨胀了几个测试视图,一切看起来都很好,直到我开始处理用户交互。
我想模拟一个切换按钮,每个问题只有一个正确答案,因此选择一个按钮应取消选择前一个按钮(如果有)。当按下按钮时,我更改了我的Question model,然后我找到所有带有findViewById 的按钮并重置它们的滤色器。然后我将该过滤器重新设置在我选择的按钮上。为了确定要更新哪个问题模型,我使用了我在模板根视图中设置的当前fragment 位置(使用setTag,在片段的 onCreate 中)。
这就是我如何称呼我的片段:
public Fragment getItem(int position) {
Question question = Repository.findById(position);
int correctAnswerBtnId;
switch (question.getCorrectAnswerIndex()) {
case 0: correctAnswerBtnId = R.id.quiz_answer_0_btn; break;
case 1: correctAnswerBtnId = R.id.quiz_answer_1_btn; break;
case 2: correctAnswerBtnId = R.id.quiz_answer_2_btn; break;
case 3: correctAnswerBtnId = R.id.quiz_answer_3_btn; break;
this.ACTIVITY_ROOT.setTag(question.getID());
Fragment fragment = new QuestionFragment();
Bundle args = new Bundle();
args.putSerializable(QuestionFragment.QUESTION, question);
fragment.setArguments(args);
return fragment;
}
我的 QuestionFragment onCreateView 是按照文档:
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle questionData) {
this.rootView = inflater.inflate(
R.layout.layout_question_template,
container,
false);
Bundle args = getArguments();
this.question = (Question) args.getSerializable(QuestionFragment.QUESTION);
populateInflatable();
rootView.findViewById(R.id.layout_question_template_root).setTag(this.question.getID());
return rootView;
}
在populateInflatable 中,我使用this.rootView 到fintViewById 并用我的问题数据填充它。然后我更改按钮的颜色,如果从问题中选择了一个。
点击按钮我打电话给selectAnserButton:
public void selectAnswerButton(View selectedButton) {
int questionId =
(int) this.activityRoot.findViewById(
R.id.layout_question_template_root).getTag(); //??
unSelectAllButtons();
changeColor(selectedButton);
Repository.findById(questionId).selectAnswer(selectedButton.getId());
}
其中unSelectAllButtons 代表四个按钮上的buttonToUnSelect.getBackground().clearColorFilter();。而Repository 只是一个带有示例问题数据的static 类。
当我有不止一种观点时,一切都变得非常错误。在每个片段上,我使用相同的视图 ID 膨胀相同的 xml,正如我定义的那样。而且据我所知,调用findViewById 不会检索一个,而是从我当前检索具有该ID 的所有视图,而且还从我的上一个和下一个fragment 检索。所以每次我想选择我当前的fragment 的视图时,我也会修改上一个和下一个fragments 中的相同视图。你可以想象这是多么有问题。这让我觉得我犯了一个根本性的错误,因为我不认为应该有多个View 和相同的ID。
我真的不明白我应该如何使用 ViewPager 来做到这一点。在这一点上,感觉就像我正在尝试制作木雕,但我正在将框架砍成碎片。使用 ViewPager 一定有更好的方法来做到这一点。
已解决:感谢 Soo Chun Jung 指出我的答案。简而言之,它对我有用的是:
- 将我的
Question modelid 传递给带有Bundle的每个片段。 - 将每个片段存储在
ArrayMap中,片段位置为key,片段为value。 - 现在很容易从我的
selectAnswer函数中获取每个片段:首先使用myViewPager.getCurrentItem获取当前片段的位置,然后调用getter函数返回当前位置上的片段。 - 现在我有了片段,我可以轻松更改其按钮,因为它们被保存为私有字段,在“onCreateView”方法中分配。
【问题讨论】:
-
如果你能显示minimal reproducible example会很有用
-
How to properly use ViewPager in android- developer.android.com/reference/android/support/v4/view/… & developer.android.com/training/animation/screen-slide.html -
另外,听起来你需要了解一下 RadioButton。 developer.android.com/guide/topics/ui/controls/radiobutton.html
-
@MarkKeen 感谢您的链接,但我已阅读文档。否则我根本无法让它工作。
-
@Gary99 RadioButtons 会有所帮助,谢谢。但它们并没有解决我的根本问题。这是如何仅在我当前的可见片段上定位视图。
标签: android android-fragments android-viewpager templating