我正在使用nested Fragment
,这是我的片段布局:
|-------------------|
| Parent fragment |
| |
| A B C |
| |
| |
|-------------------|
A、B 和 C 是我的child fragment
(扩展列表片段)。
当我启动它时fragment
,它会在大型设备中显示我想要的三盘布局。但是当我resume
从它backstack
或重新启动它(恢复)时,三个 pan viewa 没有正确显示。单击 listItem 会引发异常。view
恢复后在不同时间呈现不同的外观。每次三者之间都缺少一两个观点views
。
这是我的嵌套片段代码:
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);
}
}
}
这是大型设备的布局:
<?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>
这是小型设备的布局:
<?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" />
这是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)
这在小型设备中是可以的,因为一次只显示一个视图。每一次,这些观点都会被发现。我发现了许多类似的问题,但可能我的观点略有不同。fragments
为什么在还原中找不到这些视图?
编辑:(删除progressFragment
库代码以查看问题是否是该库)
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);
}
}
}