2

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

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

我正在使用标准的 DummyContent 来提供一些静态数据,但我已将 DummyItem 替换为我必须在此应用程序中使用的“调​​查”库。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);
    }
}

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

你可以看到,它并没有以我上面描述的方式出现。页面的内容在转换过程中也会发生变化。我相信 DummyContent 可能有问题,因为它是静态的?!

第一页 第二页 第三页 回到第二页,现在出现一个问题文本 回到第一页,现在没有问题文本了 返回第二页,再次出现另一个问题文本

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

4

2 回答 2

1

好的,我找到了答案:

我想在 onCreateView 回调中初始化使用的小部件。但后来我总是得到“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();
    }
于 2013-01-15T13:49:03.683 回答
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) {}
    });

实现片段的广播监听器。

将您的初始化方法(initWidgets()、initContent())移动到 OnCreateView 方法

它应该有效

于 2013-01-15T13:07:39.043 回答