In my application, there are some fragments
and I maintain a backstack
for them. I resume those fragment
whenever possible. fragments are resuming successfully and other operations are also performed properly. But problem is- one of them is a nested-fragment
and it has a child-fragment
inside it which is extending a listFragment
.
Everytime when I resume this fragment
, the listview
inside the child-fragmnet
is not recreating. Rather than it appending the same elements below. I mean if there are 5 list-items in real, everytime after resuming there will be 5 more same items at the end.
I have notifyDataSetChanged()
but it is not working. This is my child-fragment
code:
public class ChaptersListFragment extends SherlockListFragment {
OnChapterSelectListener mCallback;
ArrayAdapter<String> mAdapter = null;
public interface OnChapterSelectListener {
public void onChapterSelected(int position);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mAdapter != null)
mAdapter.clear(); // I try this but not working
List<String> items = new ArrayList<String>();
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);
mAdapter.notifyDataSetChanged(); // I try this but not working
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 onResume() {
super.onResume();
mAdapter.notifyDataSetChanged();
}
@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);
}
}
Moreover when I am changing the orientation, the listview is recreating and there is only 5 items then. However, after resuming several times. the application is crashed with the following logcat:
08-21 01:16:09.114: E/AndroidRuntime(664): FATAL EXCEPTION: main
08-21 01:16:09.114: E/AndroidRuntime(664): java.lang.IllegalStateException: No activity
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1075)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1861)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1474)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.os.Handler.handleCallback(Handler.java:587)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.os.Handler.dispatchMessage(Handler.java:92)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.os.Looper.loop(Looper.java:123)
08-21 01:16:09.114: E/AndroidRuntime(664): at android.app.ActivityThread.main(ActivityThread.java:4627)
08-21 01:16:09.114: E/AndroidRuntime(664): at java.lang.reflect.Method.invokeNative(Native Method)
08-21 01:16:09.114: E/AndroidRuntime(664): at java.lang.reflect.Method.invoke(Method.java:521)
08-21 01:16:09.114: E/AndroidRuntime(664): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-21 01:16:09.114: E/AndroidRuntime(664): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-21 01:16:09.114: E/AndroidRuntime(664): at dalvik.system.NativeStart.main(Native Method)
And this the parent fragment which is holding the above child fragment:
public class CompetitiveProgramming extends SherlockProgressFragment implements
OnChapterSelectListener, OnSubChapterSelectListener {
View mContentView;
static public List<Chapter> chapterList = new ArrayList<Chapter>();
private ProcessTask processTask = null;
Fragment chapterFragment = null;
Fragment subChapterFragment = null;
Fragment subSubChapterFragment = null;
@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();
chapterFragment = new ChaptersListFragment();
if (mContentView.findViewById(R.id.fragment_container) != null) {
transaction.replace(R.id.fragment_container, chapterFragment);
} else {
subChapterFragment = new SubChaptersListFragment();
subSubChapterFragment = new SubSubChaptersListFragment();
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);
}
}
}
How can I solve it? If any more code snippet is required, let me know in comment :)