android - ViewPager Fragments 不显示正确的数据

标签 android android-fragments android-viewpager

我对 Fragments 和 ViewPager 还很陌生。我正在使用 Jack Wharton 的 ActionBarSherlock 和 ViewPageIndicator。

我从标准的 Android MasterDetailFlow Activity 开始,并尝试修改它以在详细信息部分使用 ViewPager。

我正在使用标准的 DummyContent 来提供一些静态数据,但我已经用我必须在此应用程序中使用的“调​​查”-Library 替换了 DummyItem。 DummyContent 提供了一个公共(public)静态 ArrayList,我用它来填充列表 Activity 中的列表。在我在此列表中选择一个调查后,相应的问题应显示在 View 寻呼机中。

这是托管问题 fragment 的 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();
    }
}

问题 fragment .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 -> 2 -> 3 -> 2 -> 1 -> 2。

你可以看到,它并没有以我上面描述的方式出现。页面的内容在过渡期间也会发生变化。我认为 DummyContent 可能存在问题,因为它是静态的?!

first page second page third page back to second page, now a question text appears back to first page, now there is no question text any more back to second page, again another question text appears

如果我创建一个只有一个问题的调查,一切正常...

最佳答案

好的,我已经找到答案了:

我想在 onCreateView 回调中初始化使用的小部件。但后来我总是得到“java.lang.IllegalStateException:内容 View 尚未创建”。仔细一看,这只是因为 getListView() 方法。

现在我将小部件的初始化切换到 onCreateView() 回调,但 getListView() 我留在 onActivityCreated() 中。

现在一切正常, fragment 显示正确! 这就是它现在的样子:

    @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();
    }

关于android - ViewPager Fragments 不显示正确的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14335738/

相关文章:

Android - 自定义进度条

java - android中的聊天应用程序,以便发送者和接收者消息应该在不同的一边

java - 从 Activity B 返回到 Activity A 的 fragment

android - 如何更改 Android ViewPager 背景颜色?

android - PageView 中的 RecyclerView 未显示列表

Android:保留 fragment 的复杂 View 数据

Android 的 SQLite 数据库 : Failing to Open a Writeable Instance of a DB Because Could not setLocale()

android - Xamarin AndroidManifest.xml 与 Visual Studio 中的不同

java - 如何在 Java Android 中使用 ViewPager 滑动选项卡的单个 fragment

android - FragmentPagerAdapter 和 PagerAdapter 的区别