子片段未正确恢复

时间:2013-08-21 22:15:56

标签: android android-fragments

我认为我的问题非常困难,因为我在上一些问题上没有得到答案。我正在使用Fragment,我为他们维护backstack。一切正常。我在this的帮助下解决了backstack任务。

唯一的问题是 - 有一个nested fragment包含一个child fragment。当我启动它时,一切运作良好。但是当我从backstack恢复时,listview会追加到之前的listItem。我使用notifyDataSetChanged但没有任何工作。

这是嵌套的片段代码:

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);
        }
    }

}

这是儿童片段:

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);
    }

}

1 个答案:

答案 0 :(得分:1)

问题不是你在想什么!每当您恢复fragment时,每次都会调用ProcessTask。我们的chapterList并没有毁灭。结果,它每次都充满了新数据以及之前的数据。每次调用ProcessTask之前调用新实例以确保先前的数据消失。

doInBackground()内部和顶部调用此内容:

chapterList = new ArrayList<Chapter>();