Kaidul
Kaidul

Reputation: 15885

Nested Fragment java.lang.IllegalArgumentException: No view found

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

Answers (1)

Kaidul
Kaidul

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

Related Questions