Reputation: 15885
I am using nested Fragment
and this is my my fragments layout:
|-------------------|
| Parent fragment |
| |
| A B C |
| |
| |
|-------------------|
A, B & C are my child fragment
(extending list fragment).
When I launch this fragment
, it is showing three-pan layout as I want in large device. But when I resume
it from backstack
or relaunch it (resume), the three pan viewa is not showing properly. And clicking on listItem is throwing exception. The view
is showing diffrent look in different time after resuming. Everytime on or two views are missing among the three views
.
This is my nested fragment code:
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);
// if (savedInstanceState != null) {
// return;
// }
}
@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);
// if (savedInstanceState != null) {
// return;
// }
processTask = new ProcessTask();
processTask.execute();
}
protected class ProcessTask extends AsyncTask<Void, Void, List<Chapter>> {
@Override
protected List<Chapter> doInBackground(Void... params) {
InputStream inputStream = null;
List<Chapter> tempList = new ArrayList<Chapter>();
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
tempList.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 tempList;
}
@Override
protected void onPostExecute(List<Chapter> result) {
super.onPostExecute(result);
chapterList = result;
FragmentTransaction transaction = getChildFragmentManager()
.beginTransaction();
if (mContentView.findViewById(R.id.fragment_container) != null) {
transaction.replace(R.id.fragment_container, chapterFragment);
} 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);
}
}
}
This is the layout for large devices:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" >
<FrameLayout
android:id="@+id/category_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/sub_category_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/sub_sub_category_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
This is layout for small devices:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
And this is logcat:
08-22 10:12:04.175: E/AndroidRuntime(640): FATAL EXCEPTION: main
08-22 10:12:04.175: E/AndroidRuntime(640): java.lang.IllegalArgumentException: No view found for id 0x7f05002e (me.kaidul.uhunt:id/fragment_container) for fragment SubChaptersListFragment{411c0ba8 #3 id=0x7f05002e}
08-22 10:12:04.175: E/AndroidRuntime(640): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:903)
08-22 10:12:04.175: E/AndroidRuntime(640): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
08-22 10:12:04.175: E/AndroidRuntime(640): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
08-22 10:12:04.175: E/AndroidRuntime(640): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
08-22 10:12:04.175: E/AndroidRuntime(640): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
08-22 10:12:04.175: E/AndroidRuntime(640): at android.os.Handler.handleCallback(Handler.java:605)
08-22 10:12:04.175: E/AndroidRuntime(640): at android.os.Handler.dispatchMessage(Handler.java:92)
08-22 10:12:04.175: E/AndroidRuntime(640): at android.os.Looper.loop(Looper.java:137)
08-22 10:12:04.175: E/AndroidRuntime(640): at android.app.ActivityThread.main(ActivityThread.java:4424)
08-22 10:12:04.175: E/AndroidRuntime(640): at java.lang.reflect.Method.invokeNative(Native Method)
08-22 10:12:04.175: E/AndroidRuntime(640): at java.lang.reflect.Method.invoke(Method.java:511)
08-22 10:12:04.175: E/AndroidRuntime(640): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-22 10:12:04.175: E/AndroidRuntime(640): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-22 10:12:04.175: E/AndroidRuntime(640): at dalvik.system.NativeStart.main(Native Method)
This is okay in small devices as there will shown one views at a time. And every time, those views are found. I have found many similar question but may be my perspective is little different. Why those views are not found in fragments
restore?
Edit: (Remove progressFragment
library code to see whether the problem was that library)
public class CompetitiveProgramming extends SherlockFragment 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);
// if (savedInstanceState != null) {
// return;
// }
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mContentView = inflater.inflate(
R.layout.competitive_programming_exercise, container, false);
return mContentView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// setContentShown(false);
// setContentView(mContentView);
// if (savedInstanceState != null) {
// return;
// }
processTask = new ProcessTask();
processTask.execute();
}
protected class ProcessTask extends AsyncTask<Void, Void, List<Chapter>> {
@Override
protected List<Chapter> doInBackground(Void... params) {
InputStream inputStream = null;
List<Chapter> tempList = new ArrayList<Chapter>();
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
tempList.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 tempList;
}
@Override
protected void onPostExecute(List<Chapter> result) {
super.onPostExecute(result);
chapterList = result;
FragmentTransaction transaction = getChildFragmentManager()
.beginTransaction();
if (mContentView.findViewById(R.id.fragment_container) != null) {
transaction.replace(R.id.fragment_container, chapterFragment);
} 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);
}
}
}
Upvotes: 0
Views: 2995
Reputation: 15885
pass new class instance everytime instead of global instance.
Use
transaction.replace(R.id.category_fragment, new ChapterFragment());
instead of
transaction.replace(R.id.category_fragment, chapterFragment);
Upvotes: 1