儿童片段无法正常恢复 [英] Child Fragment is not restored properly
问题描述
我想我的问题是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屋!