我是Fragments和ViewPager的新手。我正在使用Jack Wharton的ActionBarSherlock和ViewPageIndicator。
我开始使用标准的Android MasterDetailFlow活动,并尝试修改它以在详细信息部分中使用ViewPager。
我正在使用标准的DummyContent来提供一些静态数据,但我已将DummyItem替换为我的“Survey” - 我必须在此应用中使用的图书馆。 DummyContent提供了一个公共静态ArrayList,我用它填充列表活动中的列表。在此列表中选择调查后,相应的问题应显示在视图寻呼机中。
以下是我的QuestionActivity.java的代码,其中包含问题片段。
public class QuestionActivity extends SherlockFragmentActivity {
private QuestionsFragmentPagerAdapter mAdapter;
private PageIndicator mIndicator;
private ViewPager mPager;
private String surveyName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_viewpager);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
surveyName = getIntent().getExtras().getString(ItemDetailFragment.ARG_SURVEY_NAME);
mAdapter = new QuestionsFragmentPagerAdapter(getSupportFragmentManager(), DummyContent.mgr.getSurvey(surveyName).getQuestions());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (PageIndicator) findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}
}
QuestionsFragmentPagerAdapter.java
public class QuestionsFragmentPagerAdapter extends FragmentPagerAdapter {
ArrayList<Question> questions;
public QuestionsFragmentPagerAdapter(FragmentManager fm, List<Question> questions) {
super(fm);
this.questions = (ArrayList<Question>) questions;
}
@Override
public Fragment getItem(int position) {
Fragment f = QuestionFragment.newInstance(questions.get(position));
return f;
}
@Override
public int getCount() {
return questions.size();
}
}
QuestionFragment.java
public class QuestionFragment extends SherlockListFragment {
protected enum QuestionType {
FT, SC, MC;
}
public final static String ARG_QUESTION_QUESTION = "question_question";
public final static String ARG_QUESTION_TYPE = "question_type";
public final static String ARG_QUESTION_ANSWERINGOPTIONS = "question_answeringptions";
private TextView lblQuestion;
private EditText txtAnswer;
private ListView listAnswers;
private ArrayAdapter<String> listAdapter;
private Question question;
private int listLayout;
/**
*
* @param question
* @return
*/
public static QuestionFragment newInstance(Question question) {
QuestionFragment fragment = new QuestionFragment();
// Creates a Bundle with all informations available in the question obj.
Bundle args = createBundleFromQuestion(question);
fragment.setArguments(args);
return fragment;
}
/**
*
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Creates the question object from the given arguments.
// I know this isn't a good solution, i will implement the
// Parcelable asap i have solved the current issues.
//
createQuestionFromBundle(getArguments());
// String questionXml = getArguments() != null ? getArguments().getString(ARG_QUESTION_XML) : null;
// this.question = (Question) MyXmlSerializer.deserialize(questionXml, Question.class);
}
/**
* Creates a the Question object form the Bundle.
* @param extras
*/
private void createQuestionFromBundle(Bundle extras) {
// Think we don't need it here. The field question gets instantiated.
}
/**
*
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.answer_question, null);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initWidgets();
setCorrectLayout();
initContent();
}
private void initContent() {
String questionStr = question.getQuestion();
lblQuestion.setText(questionStr);
if(question instanceof FTQuestion) {
} else if (question instanceof ClosedQuestion) {
listAdapter = new ArrayAdapter<String>(getActivity(), listLayout);
List<Answer> answeringOptions = question.getAnswers();
for(Answer answer : answeringOptions) {
listAdapter.add(answer.getAnswer());
}
listAnswers.setAdapter(listAdapter);
}
}
/**
*
*/
private void initWidgets() {
listAnswers = getListView();
lblQuestion = (TextView) getActivity().findViewById(R.id.lblQuestion);
txtAnswer = (EditText) getActivity().findViewById(R.id.txtAnswer);
}
/**
* Sets the FT/SC/MC layout
*/
private void setCorrectLayout() {
if(question instanceof FTQuestion) {
setFtLayout();
} else if (question instanceof SCQuestion) {
setScLayout();
} else if (question instanceof MCQuestion) {
setMcLayout();
}
}
/**
*
*/
private void setFtLayout() {
if(listAnswers.getVisibility()!=ListView.INVISIBLE && listAnswers.getVisibility()!=ListView.GONE) {
listAnswers.setVisibility(ListView.GONE);
}
}
/**
*
*/
private void setScLayout() {
listLayout = R.layout.answer_question_single_choice_list_row;
listAnswers.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
if(txtAnswer.getVisibility() == TextView.VISIBLE) txtAnswer.setVisibility(TextView.GONE);
}
/**
*
*/
private void setMcLayout() {
listLayout = R.layout.answer_question_multiple_choice_list_row;
listAnswers.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
if(txtAnswer.getVisibility() == TextView.VISIBLE) txtAnswer.setVisibility(TextView.GONE);
}
}
在列表中选择正确的调查工作正常,但现在问题显示完全错误。
实际上现在应该有3页有3个不同的问题。在第一页上应该有一个标签,上面写着“Eine tolle FT Frage?”在这个标签下面是一个EditText。在第二页上应该有一个标签,上面写着“Eine tolle SC Frage?”的问题。以及带有答案选项的列表下方。在第三页,应该有一个问题“Eine tolle MC Frage?”以及它下面的列表,其中包含与第二页相同的应答选项。
屏幕显示按顺序显示页面之间的转换:1 - &gt; 2 - &gt; 3 - &gt; 2 - &gt; 1 - &gt; 2。
你可以看到,它并没有以我上面描述的方式出现。在过渡期间,页面的内容也会发生变化。我相信DummyContent可能存在问题,因为它是静态的?!
如果我只用一个问题创建调查,一切正常......
答案 0 :(得分:1)
好的,我找到了答案:
我想在onCreateView Callback中初始化使用过的小部件。但后来我总是得到“java.lang.IllegalStateException:尚未创建的内容视图”。仔细看看,这只是因为getListView()方法。
现在我将小部件的初始化切换到onCreateView()回调,但是我在onActivityCreated()中保留了getListView()。
现在一切正常,片段显示正确! 这就是它现在的样子:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.answer_question, null);
lblQuestion = (TextView) v.findViewById(R.id.lblQuestion);
txtAnswer = (EditText) v.findViewById(R.id.txtAnswer);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listAnswers = getListView();
setCorrectLayout();
initContent();
}
答案 1 :(得分:0)
将mIndicator.setOnPageChangeListener添加到指标。并在内部发送BroadCast以获取当前页面。
indicator.setOnPageChangeListener(new OnPageChangeListener()
{
@Override
public void onPageSelected(int page) {
switch (page) {
case 0:
sendBroadcast(intent)// update your content.When broadcast come set correct layout.
break;
default:
break;
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
@Override
public void onPageScrollStateChanged(int arg0) {}
});
为片段实现广播监听器。
移动init方法(initWidgets(),initContent()) 到OnCreateView方法
应该有效