嵌套片段java.lang.IllegalArgumentException:找不到视图

时间:2013-08-22 21:22:17

标签: android android-fragments

我正在使用nested Fragment这是我的片段布局:

|-------------------|
| Parent fragment   |
|                   |
|  A    B    C      |
|                   |
|                   |
|-------------------|

A,B& C是我的child fragment(扩展列表片段)。

当我启动此fragment时,它会在大型设备中显示三个平移布局。但当我resume来自backstack或重新启动它(恢复)时,三个平移视图无法正常显示。点击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);
        }
    }

}

1 个答案:

答案 0 :(得分:1)

每次都传递新的类实例而不是全局实例。

使用

transaction.replace(R.id.category_fragment, new ChapterFragment());

而不是

transaction.replace(R.id.category_fragment, chapterFragment);