2013-08-21 82 views
0

我認爲我的問題非常困難,因爲我沒有得到有關我最後一些問題的答案。我正在使用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

問題不在於你在想什麼!每次當你恢復你的fragment時,每次都會調用ProcessTask。而我們chapterList並沒有破壞。因此,每次與以前的數據一起充滿了新數據。在調用ProcessTask之前,每次調用新實例以確保先前的數據不存在。

呼叫這裏面並在doInBackground()頂部:

chapterList = new ArrayList<Chapter>();