ViewPager Fragments未显示正确的数据

时间:2013-01-15 10:30:13

标签: android android-fragments android-viewpager

我是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可能存在问题,因为它是静态的?!

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

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

2 个答案:

答案 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方法

应该有效