儿童片段无法正常恢复 [英] Child Fragment is not restored properly

查看:125
本文介绍了儿童片段无法正常恢复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我的问题是pretty困难的,因为我没有对我的一些问题,最后得到答案。我使用片段和我保持了 backstack 他们。一切正常。我解决了的<帮助的 backstack 任务href=\"http://stackoverflow.com/questions/18305945/how-to-resume-fragment-from-backstack-if-exists/18306258?noredirect=1#comment26888812_18306258\">this.

唯一的问题是 - 有包含一个子片段 A 嵌套片段。当我启动它,一切正常。但是,当我恢复它从 backstack 列表视图与previous追加的listItem 。我用 notifyDataSetChanged ,但没有什么工作。

这是嵌套的片段code:

 包me.kaidul.uhunt;进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.io.InputStreamReader中;
进口java.lang.reflect.Field中;
进口的java.util.ArrayList;
进口的java.util.List;进口me.kaidul.uhunt.ChaptersListFragment.OnChapterSelectListener;
进口me.kaidul.uhunt.SubChaptersListFragment.OnSubChapterSelectListener;进口com.devspark.progressfragment.SherlockProgressFragment;
进口com.google.gson.stream.JsonReader;进口android.support.v4.app.Fragment;
进口android.support.v4.app.FragmentTransaction;
进口android.os.AsyncTask;
进口android.os.Bundle;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.view.ViewGroup;公共类CompetitiveProgramming扩展SherlockProgressFragment工具
        OnChapterSelectListener,OnSubChapterSelectListener {    查看mContentView;
    公共静态列表&LT;&章GT; chapterList =新的ArrayList&LT;&章GT;();
    私人ProcessTask processTask = NULL;
    片段chapterFragment =新ChaptersListFragment();
    片段subChapterFragment =新SubChaptersListFragment();
    片段subSubChapterFragment =新SubSubChaptersListFragment();    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        this.setRetainInstance(真);
    }    @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
            捆绑savedInstanceState){
        mContentView = inflater.inflate(
                R.layout.competitive_programming_exercise,集装箱,FALSE);
        返回super.onCreateView(充气器,容器,savedInstanceState);
    }    @覆盖
    公共无效onActivityCreated(捆绑savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        setContentShown(假);
        的setContentView(mContentView);
        processTask =新ProcessTask();
        processTask.execute();
    }    保护类ProcessTask扩展的AsyncTask&LT;太虚,太虚,太虚&GT; {        @覆盖
        保护无效doInBackground(虚空...... PARAMS){
            为InputStream的InputStream = NULL;
            尝试{
                的InputStream = getSherlockActivity()。getAssets()。打开(
                        CommonUtils.FILE_COMPETITIVE_PROGRAMMING_3);                JsonReader读卡器=新JsonReader(新的InputStreamReader(
                        的InputStream));                reader.beginArray(); //阵列#1
                而(reader.hasNext()){
                    字符串CHAPTERTITLE = NULL;
                    清单&LT;&子章GT;子列表=新的ArrayList&LT;&子章GT;();
                    reader.beginObject(); //对象#2
                    而(reader.hasNext()){
                        reader.skipValue();
                        CHAPTERTITLE = reader.nextString();
                        reader.skipValue();
                        reader.beginArray(); //阵列#3
                        而(reader.hasNext()){
                            字符串subChapterTitle = NULL;
                            清单&LT; SubSubChapter&GT; subSubList =新的ArrayList&LT; SubSubChapter&GT;();
                            reader.beginObject(); //对象#4
                            而(reader.hasNext()){
                                reader.skipValue();
                                subChapterTitle = reader.nextString();
                                reader.skipValue();
                                reader.beginArray(); //阵列#5
                                而(reader.hasNext()){
                                    reader.beginArray(); //阵列#6
                                    字符串subSubChapterTitle =读卡器
                                            .nextString(); //子子类
                                                            //称号
                                    清单&LT; ProblemList&GT; problemsList =新的ArrayList&LT; ProblemList&GT;();
                                    而(reader.hasNext()){
                                        INT signedProblemID = reader.nextInt(); // problemNo
                                        字符串title = reader.nextString();
                                        如果(signedProblemID℃,)
                                            problemsList.add(新ProblemList(
                                                    Math.abs(signedProblemID)
                                                    称号,真正的));
                                        其他
                                            problemsList.add(新ProblemList(
                                                    signedProblemID,标题,
                                                    假));
                                    }
                                    reader.endArray(); //阵列#6
                                    subSubList.add(新SubSubChapter(
                                            subSubChapterTitle,problemsList));
                                }
                                reader.endArray(); //阵列#5
                            }
                            reader.endObject(); //对象#4
                            subList.add(新小节(subChapterTitle,
                                    subSubList));
                        }
                        reader.endArray(); //阵列#3
                    }
                    reader.endObject(); //对象#2
                    chapterList.add(新章(CHAPTERTITLE,子表));
                }
                reader.endArray(); //阵列#1
                reader.close();            }赶上(IOException异常五){
                // 没有
            } {最后
                如果(的InputStream!= NULL){
                    尝试{
                        inputStream.close();
                    }赶上(IOException异常五){
                        // 没有
                    }
                }
            }            返回null;
        }        @覆盖
        保护无效onPostExecute(虚空结果){
            super.onPostExecute(结果);
            FragmentTransaction交易= getChildFragmentManager()
                    .beginTransaction();
            如果(mContentView.findViewById(R.id.fragment_container)!= NULL){
                transaction.replace(R.id.fragment_container,
                        新ChaptersListFragment());
            }其他{
                transaction.replace(R.id.category_fragment,chapterFragment);
                transaction.replace(R.id.sub_category_fragment,
                        subChapterFragment);
                transaction.replace(R.id.sub_sub_category_fragment,
                        subSubChapterFragment);
            }
            器transaction.commit();
            setContentShown(真);
        }    }    静态保护类{章
        串CHAPTERTITLE;
        清单&LT;&子章GT; subchapterList;        市民章(字符串CHAPTERTITLE,列表与LT;小节&GT; subchapterList){
            this.chapterTitle = CHAPTERTITLE;
            this.subchapterList = subchapterList;
        }    }    静态保护类小节{
        串subChapterTitle;
        清单&LT; SubSubChapter&GT; subsubchapterList;        公共小节(字符串subChapterTitle,
                清单&LT; SubSubChapter&GT; subsubchapterList){
            this.subChapterTitle = subChapterTitle;
            this.subsubchapterList = subsubchapterList;
        }    }    静态保护类SubSubChapter {
        串subSubChapterTitle;
        清单&LT; ProblemList&GT; problemList;        公共SubSubChapter(字符串subSubChapterTitle,
                清单&LT; ProblemList&GT; problemList){
            this.subSubChapterTitle = subSubChapterTitle;
            this.problemList = problemList;
        }    }    静态公共类ProblemList {
        整数problemNo;
        串problemTitle;
        布尔isStarred;        公共ProblemList(整数problemNo,字符串problemTitle,
                布尔isStarred){
            this.problemNo = problemNo;
            this.isStarred = isStarred;
            this.problemTitle = problemTitle;
        }    }    @覆盖
    公共无效onChapterSelected(INT位置){
        SubChaptersListFragment subChaptersListFrag =(SubChaptersListFragment)getChildFragmentManager()
                .findFragmentById(R.id.sub_category_fragment);
        如果(subChaptersListFrag!= NULL){
            subChaptersListFrag.updateList(位置);
        }其他{
            subChapterFragment =新SubChaptersListFragment();
            捆绑ARGS =新包();
            args.putInt(SubChaptersListFragment.CHAPTER_POSITION,位置);
            subChapterFragment.setArguments(参数);
            FragmentTransaction交易= getChildFragmentManager()
                    .beginTransaction();
            transaction.replace(R.id.fragment_container,subChapterFragment);
            器transaction.commit();
        }
    }    @覆盖
    公共无效onSubChapterSelected(INT preV,INT位置){
        SubSubChaptersListFragment subSubChaptersListFrag =(SubSubChaptersListFragment)getChildFragmentManager()
                .findFragmentById(R.id.sub_sub_category_fragment);
        如果(subSubChaptersListFrag!= NULL){
            subSubChaptersListFrag.updateList(preV,位置);
        }其他{
            subSubChapterFragment =新SubSubChaptersListFragment();
            捆绑ARGS =新包();
            args.putIntArray(SubSubChaptersListFragment.POSITIONS,新的INT [] {
                    preV,位置});
            subSubChapterFragment.setArguments(参数);
            FragmentTransaction交易= getChildFragmentManager()
                    .beginTransaction();
            transaction.replace(R.id.fragment_container,subSubChapterFragment);
            器transaction.commit();
        }
    }    @覆盖
    公共无效的onStop(){
        super.onStop();
        如果(processTask!= NULL
                &功放;&安培; processTask.getStatus()!= AsyncTask.Status.FINISHED){
            processTask.cancel(真);
        }
    }    @覆盖
    公共无效onDestroyView(){        尝试{
            FragmentTransaction交易= getChildFragmentManager()
                    .beginTransaction();
            transaction.remove(chapterFragment);
            器transaction.commit();
        }赶上(例外五){
        }        super.onDestroyView();
    }    @覆盖
    公共无效onDetach(){
        super.onDetach();
        尝试{
            现场childFragmentManager = Fragment.class
                    .getDeclaredField(mChildFragmentManager);
            childFragmentManager.setAccessible(真);
            childFragmentManager.set(这一点,空);        }赶上(NoSuchFieldException E){
            抛出新的RuntimeException(E);
        }赶上(IllegalAccessException E){
            抛出新的RuntimeException(E);
        }
    }}

这是孩子的片段:

 包me.kaidul.uhunt;进口的java.util.ArrayList;
进口的java.util.List;进口android.app.Activity;
进口android.os.Bundle;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.view.ViewGroup;
进口android.widget.ArrayAdapter;
进口android.widget.ListView;进口com.actionbarsherlock.app.SherlockListFragment;公共类ChaptersListFragment扩展SherlockListFragment {    OnChapterSelectListener mCallback;
    ArrayAdapter&LT;串GT; mAdapter;
    清单&LT;串GT;项目=新的ArrayList&LT;串GT;();    公共接口OnChapterSelectListener {
        公共无效onChapterSelected(INT位置);
    }    @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
            捆绑savedInstanceState){
        返回super.onCreateView(充气器,容器,savedInstanceState);
    }    @覆盖
    公共无效onActivityCreated(捆绑savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        如果(savedInstanceState == NULL){
            items.clear();
            的for(int i = 0; I&LT; CompetitiveProgramming.chapterList.size();我++){
                items.add(CompetitiveProgramming.chapterList.get㈠.chapterTitle);
            }
            mAdapter =新ArrayAdapter&LT;串GT;(getSherlockActivity()
                    R.layout.list_layout,项目);
            setListAdapter(mAdapter);
        }
    }    @覆盖
    公共无效调用onStart(){
        super.onStart();
        如果(getFragmentManager()。findFragmentById(R.id.sub_category_fragment)!= NULL){
            。getListView()setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        }
    }    @覆盖
    公共无效onAttach(活动活动){
        super.onAttach(活动);
        尝试{
            mCallback =(OnChapterSelectListener)getParentFragment();
        }赶上(抛出ClassCastException E){
            抛出新ClassCastException异常(getParentFragment()。的toString()
                    +必须实现OnChapterSelectListener);
        }
    }    @覆盖
    公共无效onListItemClick(ListView中升,视图V,INT位置,长的id){
        mCallback.onChapterSelected(位置);
        getListView()setItemChecked(位置,真)。
    }}


解决方案

这个问题是不是你在想什么!当你恢复你的片段每次时间 ProcessTask 被称为每次。而我们的 chapterList 未破坏。其结果是,它与新的数据,每次使用previous数据一起填充。调用新的实例每次 ProcessTask 之前调用,以确保previous数据已经一去不复返了。

调用这里面,并在的顶部doInBackground()

  chapterList =新的ArrayList&LT;&章GT;();

I think my problem is pretty difficult as I didn't get answer on some of my last questions. I am using Fragment and I am maintaining a backstack for them. Everything is okay. I solved the backstack task with help of this.

The only problem is that - there is a nested fragment containing one child fragment. When I launch it, everything works well. But when I resume it from backstack, the listview is appending with the previous listItem. I used notifyDataSetChanged but nothing is working.

This is the nested fragment code:

package me.kaidul.uhunt;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import me.kaidul.uhunt.ChaptersListFragment.OnChapterSelectListener;
import me.kaidul.uhunt.SubChaptersListFragment.OnSubChapterSelectListener;

import com.devspark.progressfragment.SherlockProgressFragment;
import com.google.gson.stream.JsonReader;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class CompetitiveProgramming extends SherlockProgressFragment implements
        OnChapterSelectListener, OnSubChapterSelectListener {

    View mContentView;
    public static List<Chapter> chapterList = new ArrayList<Chapter>();
    private ProcessTask processTask = null;
    Fragment chapterFragment = new ChaptersListFragment();
    Fragment subChapterFragment = new SubChaptersListFragment();
    Fragment subSubChapterFragment = new SubSubChaptersListFragment();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mContentView = inflater.inflate(
                R.layout.competitive_programming_exercise, container, false);
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setContentShown(false);
        setContentView(mContentView);
        processTask = new ProcessTask();
        processTask.execute();
    }

    protected class ProcessTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            InputStream inputStream = null;
            try {
                inputStream = getSherlockActivity().getAssets().open(
                        CommonUtils.FILE_COMPETITIVE_PROGRAMMING_3);

                JsonReader reader = new JsonReader(new InputStreamReader(
                        inputStream));

                reader.beginArray(); // array #1
                while (reader.hasNext()) {
                    String chapterTitle = null;
                    List<SubChapter> subList = new ArrayList<SubChapter>();
                    reader.beginObject(); // object #2
                    while (reader.hasNext()) {
                        reader.skipValue();
                        chapterTitle = reader.nextString();
                        reader.skipValue();
                        reader.beginArray(); // array #3
                        while (reader.hasNext()) {
                            String subChapterTitle = null;
                            List<SubSubChapter> subSubList = new ArrayList<SubSubChapter>();
                            reader.beginObject(); // object #4
                            while (reader.hasNext()) {
                                reader.skipValue();
                                subChapterTitle = reader.nextString();
                                reader.skipValue();
                                reader.beginArray(); // array #5
                                while (reader.hasNext()) {
                                    reader.beginArray(); // array #6
                                    String subSubChapterTitle = reader
                                            .nextString(); // sub-sub-category
                                                            // title
                                    List<ProblemList> problemsList = new ArrayList<ProblemList>();
                                    while (reader.hasNext()) {
                                        int signedProblemID = reader.nextInt(); // problemNo
                                        String title = reader.nextString();
                                        if (signedProblemID < 0)
                                            problemsList.add(new ProblemList(
                                                    Math.abs(signedProblemID),
                                                    title, true));
                                        else
                                            problemsList.add(new ProblemList(
                                                    signedProblemID, title,
                                                    false));
                                    }
                                    reader.endArray(); // array #6
                                    subSubList.add(new SubSubChapter(
                                            subSubChapterTitle, problemsList));
                                }
                                reader.endArray(); // array #5
                            }
                            reader.endObject(); // object #4
                            subList.add(new SubChapter(subChapterTitle,
                                    subSubList));
                        }
                        reader.endArray(); // array #3
                    }
                    reader.endObject(); // object #2
                    chapterList.add(new Chapter(chapterTitle, subList));
                }
                reader.endArray(); // array #1
                reader.close();

            } catch (IOException e) {
                // nothing
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        // nothing
                    }
                }
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            FragmentTransaction transaction = getChildFragmentManager()
                    .beginTransaction();
            if (mContentView.findViewById(R.id.fragment_container) != null) {
                transaction.replace(R.id.fragment_container,
                        new ChaptersListFragment());
            } else {
                transaction.replace(R.id.category_fragment, chapterFragment);
                transaction.replace(R.id.sub_category_fragment,
                        subChapterFragment);
                transaction.replace(R.id.sub_sub_category_fragment,
                        subSubChapterFragment);
            }
            transaction.commit();
            setContentShown(true);
        }

    }

    static protected class Chapter {
        String chapterTitle;
        List<SubChapter> subchapterList;

        public Chapter(String chapterTitle, List<SubChapter> subchapterList) {
            this.chapterTitle = chapterTitle;
            this.subchapterList = subchapterList;
        }

    }

    static protected class SubChapter {
        String subChapterTitle;
        List<SubSubChapter> subsubchapterList;

        public SubChapter(String subChapterTitle,
                List<SubSubChapter> subsubchapterList) {
            this.subChapterTitle = subChapterTitle;
            this.subsubchapterList = subsubchapterList;
        }

    }

    static protected class SubSubChapter {
        String subSubChapterTitle;
        List<ProblemList> problemList;

        public SubSubChapter(String subSubChapterTitle,
                List<ProblemList> problemList) {
            this.subSubChapterTitle = subSubChapterTitle;
            this.problemList = problemList;
        }

    }

    static public class ProblemList {
        Integer problemNo;
        String problemTitle;
        boolean isStarred;

        public ProblemList(Integer problemNo, String problemTitle,
                boolean isStarred) {
            this.problemNo = problemNo;
            this.isStarred = isStarred;
            this.problemTitle = problemTitle;
        }

    }

    @Override
    public void onChapterSelected(int position) {
        SubChaptersListFragment subChaptersListFrag = (SubChaptersListFragment) getChildFragmentManager()
                .findFragmentById(R.id.sub_category_fragment);
        if (subChaptersListFrag != null) {
            subChaptersListFrag.updateList(position);
        } else {
            subChapterFragment = new SubChaptersListFragment();
            Bundle args = new Bundle();
            args.putInt(SubChaptersListFragment.CHAPTER_POSITION, position);
            subChapterFragment.setArguments(args);
            FragmentTransaction transaction = getChildFragmentManager()
                    .beginTransaction();
            transaction.replace(R.id.fragment_container, subChapterFragment);
            transaction.commit();
        }
    }

    @Override
    public void onSubChapterSelected(int prev, int position) {
        SubSubChaptersListFragment subSubChaptersListFrag = (SubSubChaptersListFragment) getChildFragmentManager()
                .findFragmentById(R.id.sub_sub_category_fragment);
        if (subSubChaptersListFrag != null) {
            subSubChaptersListFrag.updateList(prev, position);
        } else {
            subSubChapterFragment = new SubSubChaptersListFragment();
            Bundle args = new Bundle();
            args.putIntArray(SubSubChaptersListFragment.POSITIONS, new int[] {
                    prev, position });
            subSubChapterFragment.setArguments(args);
            FragmentTransaction transaction = getChildFragmentManager()
                    .beginTransaction();
            transaction.replace(R.id.fragment_container, subSubChapterFragment);
            transaction.commit();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (processTask != null
                && processTask.getStatus() != AsyncTask.Status.FINISHED) {
            processTask.cancel(true);
        }
    }

    @Override
    public void onDestroyView() {

        try {
            FragmentTransaction transaction = getChildFragmentManager()
                    .beginTransaction();
            transaction.remove(chapterFragment);
            transaction.commit();
        } catch (Exception e) {
        }

        super.onDestroyView();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        try {
            Field childFragmentManager = Fragment.class
                    .getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

}

And this is the child fragment:

package me.kaidul.uhunt;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.actionbarsherlock.app.SherlockListFragment;

public class ChaptersListFragment extends SherlockListFragment {

    OnChapterSelectListener mCallback;
    ArrayAdapter<String> mAdapter;
    List<String> items = new ArrayList<String>();

    public interface OnChapterSelectListener {
        public void onChapterSelected(int position);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState == null) {
            items.clear();
            for (int i = 0; i < CompetitiveProgramming.chapterList.size(); i++) {
                items.add(CompetitiveProgramming.chapterList.get(i).chapterTitle);
            }
            mAdapter = new ArrayAdapter<String>(getSherlockActivity(),
                    R.layout.list_layout, items);
            setListAdapter(mAdapter);
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        if (getFragmentManager().findFragmentById(R.id.sub_category_fragment) != null) {
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mCallback = (OnChapterSelectListener) getParentFragment();
        } catch (ClassCastException e) {
            throw new ClassCastException(getParentFragment().toString()
                    + " must implement OnChapterSelectListener");
        }
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        mCallback.onChapterSelected(position);
        getListView().setItemChecked(position, true);
    }

}

解决方案

The problem is not what you're thinking! Every-time when you're resuming your fragment, ProcessTask is called each time. And our chapterList is not destroying. As a result, it is filled up with new data everytime along with the previous data. Call new instances everytime before calling ProcessTask to make sure that previous data is gone.

Call this inside and at the top of doInBackground():

chapterList = new ArrayList<Chapter>();

这篇关于儿童片段无法正常恢复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆