Search code examples
androidandroid-fragmentsback-stackandroid-nested-fragment

Nested Fragment with backstack Resume


In my application there are several fragments in an activity and I am maintaining a backStack for these fragment. Everything is okay, but there is a nested fragment among them. When I put it into backStack and again resume in by pressing back button, the fragment looks overllaping previous content (child fragment). This is the normal view:

enter image description here

This is the screenshot of overlapping view (when I resume the fragment):

enter image description here

You can get the difference as the second one's text is more deep (that means child fragment is overlapping)

How can I avoid that? This the code for my nested fragment:

public class CompetitiveProgramming extends SherlockProgressFragment implements
        OnChapterSelectListener, OnSubChapterSelectListener {

    View mContentView;
    static public List<Chapter> chapterList = new ArrayList<Chapter>();
    private ProcessTask processTask = 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) {
            // background task
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            FragmentTransaction transaction = getChildFragmentManager()
                    .beginTransaction();
            if (mContentView.findViewById(R.id.fragment_container) != null) {
                getChildFragmentManager().beginTransaction()
                        .add(R.id.fragment_container, new ChaptersListFragment()).commit();
            } else {
                transaction.add(R.id.category_fragment, new ChaptersListFragment());
                transaction.add(R.id.sub_category_fragment, new SubChaptersListFragment());
                transaction.add(R.id.sub_sub_category_fragment,
                        new SubSubChaptersListFragment());
            }
            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;
        }

    }

    @Override
    public void onChapterSelected(int position) {
        SubChaptersListFragment subChaptersListFrag = (SubChaptersListFragment) getChildFragmentManager()
                .findFragmentById(R.id.sub_category_fragment);
        if (subChaptersListFrag != null) {
            subChaptersListFrag.updateList(position);
        } else {
            SubChaptersListFragment 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.addToBackStack(null);
            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 {
            SubSubChaptersListFragment 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.addToBackStack(null);
            transaction.commit();           
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (processTask != null && processTask.getStatus() != AsyncTask.Status.FINISHED) {
            processTask.cancel(true);
        }
    }

}

Solution

  • Kirill Kulakov is right. replace instead of add should be used. I edited the code:

    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) {
                // background task
                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;
            }
    
        }
    
        @Override
        public void onChapterSelected(int position) {
            SubChaptersListFragment subChaptersListFrag = (SubChaptersListFragment) getChildFragmentManager()
                    .findFragmentById(R.id.sub_category_fragment);
            if (subChaptersListFrag != null) {
                subChaptersListFrag.updateList(position);
            } else {
                SubChaptersListFragment 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.addToBackStack(null);
                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 {
                SubSubChaptersListFragment 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.addToBackStack(null);
                transaction.commit();           
            }
        }
    
        @Override
        public void onStop() {
            super.onStop();
            if (processTask != null && processTask.getStatus() != AsyncTask.Status.FINISHED) {
                processTask.cancel(true);
            }
        }
    
    }
    

    Hope this would help!