在ViewPager中恢复片段状态时的问题(使用FragmentStatePagerAdapter)

时间:2016-01-12 15:44:01

标签: android android-fragments android-viewpager fragmentpageradapter

我将难以解释这里的问题,但我会尝试。

所以我有一个ViewPager,其中包含很多Fragment,由FragmentStatePagerAdapter管理,这些Fragment是与抽象类{{1}相关的卡片}有多个孩子QuestionTrueFalseQuestion等。但只有MultipleChoiceQuestion的{​​{1}}类型Fragment

QuestionFragment

所以我必须保存用户的输入和服务器在onSaveInstanceState上发送的答案,以便在配置更改时正确重建。

但是当我改变方向时,我放松了用户输入。

您会找到一个名为public class QuestionFragment extends ElementFragment { public static String ARG_DATA = "c0pcjOLtwAoIMDe1lwJ4"; protected static String ARG_SOURCE = "source"; protected static String ARG_ANWSER_CORRECTION = "LPYmZpVmnhssq762mLpu"; protected static String ARG_COURSE_MODE = "COURSEMODE"; protected ElementViewerActivity.Source source; protected Question mQuestion; protected QuestionType mQtype; protected CollectedAnswers userAnswer; protected QuestionAnswerResponse serverResponse; protected QuestionViewHolder holder; private CourseMode mCourseMode; /*Lot of different newInstance here, I don't think they are relevant*/ public QuestionFragment() { // Required empty public constructor } @Override public void onSaveInstanceState(Bundle outState) { //Log.i("renaud", "savingInstanceState : userAnswer==null?:" + (userAnswer == null) + " | serverResponse==null?:" + (serverResponse == null)); outState.putSerializable("userAnswer", userAnswer); outState.putSerializable("serverResponse", serverResponse); Log.i("renaud","question fragment state saved"); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mQuestion = (Question) getArguments().get(ARG_DATA); Log.e("ID ",this.toString()); setRetainInstance(true); source = (ElementViewerActivity.Source) getArguments().get(ARG_SOURCE); mCourseMode = (CourseMode) getArguments().get(ARG_COURSE_MODE); QuestionAnswerCorrection questionAnswerCorrection = (QuestionAnswerCorrection) getArguments().get(ARG_ANWSER_CORRECTION); if(questionAnswerCorrection!= null && savedInstanceState==null){ userAnswer = questionAnswerCorrection.userAnswer; serverResponse = questionAnswerCorrection.serverResponse; } mQtype = mQuestion.getQtype(); Activity activity = getActivity(); switch (mQtype) { case TRUE_FALSE: holder = new QuestionTFViewHolder(activity, mQuestion); Log.e("DEBUG --TF-- ","holder = new QuestionTFViewHolder(activity, mQuestion)"); break; case MULTIPLE_CHOICES: holder = new QuestionMCViewHolder(activity, mQuestion); Log.e("DEBUG --MC-- ","holder = new QuestionMCViewHolder(activity, mQuestion)"); break; case ORDER: holder = new QuestionOrderViewHolder(activity, mQuestion); break; case LINKER: holder = new QuestionLinkerViewHolder(activity, mQuestion); break; case OPEN: holder = new QuestionOpenViewHolder(activity, mQuestion); break; case AREA: holder = new QuestionAreaViewHolder(activity, mQuestion); break; default: Log.e("renaud", "Question non traitée " + mQtype); break; } // Inflate the layout for this fragment if (savedInstanceState != null) { Log.i("renaud","restore onCreateView :"+mQtype.name()); Serializable serializedUserAnswer = savedInstanceState.getSerializable("userAnswer"); if(serializedUserAnswer instanceof BooleanCollectedAnswer){ userAnswer = (BooleanCollectedAnswer) serializedUserAnswer; Log.e("renaud","serializedUserAnswer instanceof BooleanCollectedAnswer"); } else if(serializedUserAnswer instanceof CoordinateCollectedAnswer) { userAnswer = (CoordinateCollectedAnswer) serializedUserAnswer; Log.e("renaud","serializedUserAnswer instanceof CoordinateCollectedAnswer"); } else if (serializedUserAnswer instanceof IntegerListCollectedAnswer) { userAnswer = (IntegerListCollectedAnswer) serializedUserAnswer; Log.e("renaud","serializedUserAnswer instanceof IntegerListCollectedAnswer"); } else if (serializedUserAnswer instanceof OpenCollectedAnswer) { userAnswer = (OpenCollectedAnswer) serializedUserAnswer; Log.e("renaud","serializedUserAnswer instanceof OpenCollectedAnswer"); }else{ Log.e("renaud","bug"); } //userAnswer = (CollectedAnswers) savedInstanceState.getSerializable("userAnswer"); serverResponse = (QuestionAnswerResponse) savedInstanceState.getSerializable("serverResponse"); Log.i("renaud", "Question fragment SAVED INSTANCE STATE NOT NULL (userAnswer==null)=" + (userAnswer == null) + " | (serverResponse==null):" + (serverResponse == null)); } View v = null; switch (mQtype) { case TRUE_FALSE: v = inflater.inflate(R.layout.fragment_question_container, container, false); break; case MULTIPLE_CHOICES: v = inflater.inflate(R.layout.fragment_question_container, container, false); break; case ORDER: v = inflater.inflate(R.layout.fragment_question_container, container, false); break; case LINKER: v = inflater.inflate(R.layout.fragment_question_container, container, false); break; case OPEN: v = inflater.inflate(R.layout.fragment_question_container, container, false); break; case AREA: v = inflater.inflate(R.layout.fragment_question_container, container, false); default: Log.e("renaud", "Question non traitée " + mQtype); break; } holder.initWithView(v, new SendResponseOnClicListener()); //Quand une question est vue dans l'elementViewer, cad lancé depuis le news feed, on ne peut pas envoyer la réponse. if (source == ElementViewerActivity.Source.VIEWER) { holder.sendAnswer.setVisibility(View.GONE); } if (serverResponse != null || userAnswer != null) { //Log.i("renaud", "server response != null ? " + (serverResponse != null)); //Log.i("renaud", "userAnswer != null ? " + (userAnswer != null)); Log.i("renaud","savedInstanceState != null, (userAnswer!=null):"+(userAnswer!=null)); holder.setCollectedAnswers(userAnswer); holder.answerSentSetDisable(); if(mCourseMode !=null && mCourseMode == CourseMode.TRAINING) { holder.fillCorrection(serverResponse); } /*if(holder instanceof QuestionMCViewHolder){ QuestionMCViewHolder mcViewHolder = (QuestionMCViewHolder) holder; for(int i = 0; i< mcViewHolder.mcLayout.getChildCount();i++){ Log.i("Renaud","test dans question fragment :"+((CheckBox) mcViewHolder.mcLayout.getChildAt(i)).isChecked()); } }*/ } return v; } public void logTest(){ if(holder instanceof QuestionMCViewHolder){ Log.i("renaud","it's a question mc view holder"); QuestionMCViewHolder mcViewHolder = (QuestionMCViewHolder) holder; for(int i = 0; i< mcViewHolder.mcLayout.getChildCount();i++){ Log.i("Renaud","test dans question fragment :"+((CheckBox) mcViewHolder.mcLayout.getChildAt(i)).isChecked()); } } else if(holder instanceof QuestionOrderViewHolder) { Log.i("renaud","it's a QuestionOrderViewHolder"); } else if (holder instanceof QuestionLinkerViewHolder) { Log.i("renaud","it's a QuestionLinkerViewHolder"); } else if (holder instanceof QuestionTFViewHolder) { Log.i("renaud","it's a QuestionTFViewHolder"); } else if (holder instanceof QuestionOpenViewHolder) { Log.i("renaud","it's a QuestionOpenViewHolder"); } else if (holder instanceof QuestionAreaViewHolder) { Log.i("renaud","it's a QuestionAreaViewHolder"); }else{ Log.e("ID ",this.toString()); Log.i("renaud","holder is nothing!"); Log.i("renaud","holder ==null ?"+(holder==null)); Log.i("renaud","(holder instanceof QuestionViewHolder) ?"+(holder instanceof QuestionViewHolder)); } } public class SendResponseOnClicListener implements View.OnClickListener { @Override public void onClick(final View v) { holder.answerSentSetDisable(); //TODO ARE ALL DOCUMENTS UPLOADED WHEN IT'S AN OPEN QUESTION ? //final QuestionOpenViewHolder openHolder = (QuestionOpenViewHolder) holder; userAnswer = holder.collectAnswer(); new Thread(new Runnable() { @Override public void run() { try { final QuestionAnswerResponse response = CourseRepository.getInstance().postQuestionAnswer(mQuestion.getId(), mQuestion.getCreatedFor(), userAnswer); EventBus.getDefault().post(new EnableNextEvent(mQuestion.getId())); getActivity().runOnUiThread(new Runnable() { @Override public void run() { serverResponse = response; if(mCourseMode !=null && mCourseMode == CourseMode.TRAINING) { holder.fillCorrection(serverResponse); } //holder.fillCorrection(response); } }); } catch (Exception e) { e.printStackTrace(); } } }).start(); } } public class AnswerCollectedEvent { public CollectedAnswers userAnswer; public QuestionAnswerResponse serverResponse; public String questionId; public AnswerCollectedEvent(String questionId, CollectedAnswers userAnswer, QuestionAnswerResponse serverResponse) { this.userAnswer = userAnswer; this.questionId = questionId; this.serverResponse = serverResponse; } } public static class EnableNextEvent { public String id; public EnableNextEvent(String id) { this.id = id; } } @Override public void onStop() { //EventBus.getDefault().unregister(this); super.onStop(); } @Override public void onStart() { //EventBus.getDefault().register(this); super.onStart(); } } 的方法,我创建该方法以查看问题所在。我在viewPager更改其页面时调用它,似乎我总是得到这些日志:

public void logTest()

并且片段的Id与onCreate中的ID不同:

E/ID: QuestionFragment{edb2fad}
holder is nothing!
holder ==null ?true
(holder instanceof QuestionViewHolder) ?false

所以我认为我有两倍的片段而且显示了错误的片段,但在我的Activity onCreate中我测试了我有多少片段:

/ID: QuestionFragment{68fc4ae #1 id=0x7f0e00a5}

似乎我的数量很多。所以我创建Fragments Every Logs表示他们有更正用户输入,我将它们逐个添加到我的适配器,其中只包含其中的那些,但当我切换页面时,并调用它:

mPagerAdapter.addItem(QuestionFragment.newInstance(question, ElementViewerActivity.Source.PLAYER, mCourseMode));
Log.e("renaud", "restore count mPagerAdapter : " + mPagerAdapter.getFragmentResgisteredCount());

调用日志测试但是我在上面给出了结果......

---编辑---

Log.i("renaud","page selected "+position);
Fragment fragment = mPagerAdapter.getItem(position);
if(fragment instanceof QuestionFragment){
   Log.i("renaud","it's a question fragment");
   ((QuestionFragment) fragment).logTest();
}
public class QuestionMCViewHolder extends QuestionViewHolder {

    public LinearLayout mcLayout;

    public QuestionMCViewHolder(Activity activity, Question question) {
        super(activity, question);
    }

    private LayoutInflater inflater;

    @Override
    public void initWithView(View v, QuestionFragment.SendResponseOnClicListener onClicListener) {

        Log.i("renaud","QuestionMCViewHolder initWithView");

        super.initWithView(v, onClicListener);

        inflater = LayoutInflater.from(mActivity);
        container.addView(inflater.inflate(R.layout.fragment_question_container_mc, null));
        mcLayout = (LinearLayout) v.findViewById(R.id.mc_layout);

        for (String text : question.getAnswers()) {
            CheckBox cb = (CheckBox) inflater.inflate(R.layout.fragment_question_container_mc_item, null);
            cb.setText(text);
            cb.setChecked(false);
            mcLayout.addView(cb);
        }


    }


    @Override
    public void fillCorrection(QuestionAnswerResponse answer) {
        super.fillCorrection(answer);


        View v = inflater.inflate(R.layout.fragment_question_container_mc, null);
        LinearLayout answerLayout = (LinearLayout) v.findViewById(R.id.mc_layout);


        for (Integer position : answer.getAnswers()) {
            CheckBox cb = (CheckBox) inflater.inflate(R.layout.fragment_question_container_mc_item, null);


            cb.setText(question.getAnswers().get(position));
            cb.setChecked(true);
            cb.setEnabled(false);
            //cb.setBackgroundResource(R.color.question_true);
            answerLayout.addView(cb);
        }
        correctionSpecificContainer.addView(v);

        AnimationUtils.expand(correctionLayout);
    }

    @Override
    public IntegerListCollectedAnswer collectAnswer() {

        IntegerListCollectedAnswer answer = new IntegerListCollectedAnswer();
        for (int i = 0; i < mcLayout.getChildCount(); i++) {
            if (((CheckBox) mcLayout.getChildAt(i)).isChecked()) {
                answer.list.add(i);
            }
        }
        return answer;
    }

    @Override
    public void setCollectedAnswers(CollectedAnswers answers) {

        Log.w("renaud","QuestionMCViewHolder setCollectedAnswers");

        if (answers instanceof IntegerListCollectedAnswer) {
            IntegerListCollectedAnswer integers = (IntegerListCollectedAnswer) answers;

            //mcLayout.removeAllViews();

            for (int i = 0; i < question.getAnswers().size(); i++) {
                CheckBox cb = (CheckBox) mcLayout.getChildAt(i);  //inflater.inflate(R.layout.fragment_question_container_mc_item, null);
                //cb.setText(question.getAnswers().get(i));
                //Log.i("QUESTIONMC SETCOLLECTED", "integers.list.contains(i) = " + integers.list.contains(i));

                //mcLayout.addView(cb);
                cb.setChecked(integers.list.contains(i));
                Log.d("renaud", "setCollectedAnswers cb.isChecked():"+cb.isChecked());
            }



        } else {
            Log.i("renaud", "CollectedAnswers instanceof IntegerListCollectedAnswer failed");
        }


    }
}
public class IntegerListCollectedAnswer extends CollectedAnswers {
    public ArrayList<Integer> list = new ArrayList<>();

    public IntegerListCollectedAnswer(ArrayList<Integer> list) {
        this.list = list;
    }

    public IntegerListCollectedAnswer() {
    }
}

谢谢,

0 个答案:

没有答案