2

私は Fragments と ViewPager でかなり新しいです。Jack Wharton の ActionBarSherlock と ViewPageIndicator を使用しています。

私は標準の Android MasterDetailFlow アクティビティから始めて、詳細部分で ViewPager を使用するように変更しようとしました。

標準の DummyContent を使用して静的データを提供していますが、DummyItem をこのアプリで使用する必要がある「Survey」ライブラリに置き換えました。DummyContent は、リスト アクティビティでリストを埋めるために使用する public static 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 があります。2 ページ目には、「Eine tolle SC Frage?」という質問のラベルがあるはずです。回答オプションのリストの下にあります。3 ページに「Eine tolle MC Frage?」という質問があります。また、その下には、2 ページ目と同じ回答オプションを含むリストがあります。

スクリーンショットは、1 -> 2 -> 3 -> 2 -> 1 -> 2 の順序でページ間の遷移を示しています。

上記で説明した方法では表示されないことがわかります。ページのコンテンツも移行中に変更されます。DummyContent は静的であるため、問題が発生する可能性があると思いますか?!

先頭ページ 2ページ目 3ページ目 2 ページ目に戻ると、質問テキストが表示されます 最初のページに戻ると、問題文はもうありません 2 ページ目に戻ると、再び別の問題文が表示されます

質問が 1 つだけのアンケートを作成すると、すべて正常に機能します...

4

2 に答える 2

1

さて、私は答えを見つけました:

onCreateView Callback で使用されているウィジェットを初期化したかったのです。しかし、その後、常に「java.lang.IllegalStateException: コンテンツ ビューがまだ作成されていません」というメッセージが表示されました。よく見ると、これは単に getListView() メソッドが原因であることがわかりました。

ここで、ウィジェットの初期化を onCreateView() コールバックに切り替えましたが、getListView() は onActivityCreated() に残しました。

すべてが正常に動作し、フラグメントが正しく表示されるようになりました! それが今の様子です:

    @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 に答える