Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Viewpager in fragment is not shown(restored) when go back from other fragment

I'm facing the problem as following: In main screen, I have 3 buttons: Config, Main, Setting.

  • When each button is clicked, a corresponding fragment will be shown to inflate layout in a FrameLayout.
  • When user is in Config or Setting Fragment, it is able to go back to main Fragment using onBackpressed or click on the button Main. When user is in Main Fragment, if user click on Back, a popup is shown to confirm exit.

In the main Fragment, I put a viewpager. Inside this viewpager, I put 2 other fragments, each of them contains a grid of images( I also used a circle indicator to see the page changes in the bottom). For simplicity, Config Fragment and Setting Fragment only show a Text in the center. When app start, in showed normally Main fragment, when I click on button Setting or Config, it showed normally corresponding fragments. The problem is when click on Back button (on Android), it go back to Main Fragment but without fragments inside viewpager. It showed empty screen.

Main fragment- fragment 1 in viewpager is shownMain fragment - fragment 2 in viewpager is shownConfig fragment Setting fragmentGo back to main fragment from config/setting fragment

Maybe I'm wrong when process going back from config/setting fragment to main fragment. If main fragment just inflate a certain layout without viewpager, the problem will not happen. How to restore state of viewpager when go back to main fragment from config/setting fragment? I'm attaching my code so that you could give me more clear answer. Thank you very much for any answer.

package com.example.testfragmentviewpager;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.FrameLayout;

import com.example.viewpageindicator.CirclePageIndicator;
import com.example.viewpageindicator.PageIndicator;

public class MainActivity extends FragmentActivity {

    Fragment configFragment;
    Fragment settingFragment;
    Fragment mainItemsFragment;
    FrameLayout frmLayout;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.main);

        if (savedInstanceState == null) {
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            frmLayout = (FrameLayout) findViewById(R.id.frame_cotainer);
            mainItemsFragment = new MainItemsFragment();
            ft.add(R.id.frame_cotainer, mainItemsFragment, "mainItems").commit();
        }

        addListener(R.id.btnConfig);
        addListener(R.id.btnMain);
        addListener(R.id.btnSetting);

    }

    public void addListener(int buttonID) {
        final Button btn = (Button) findViewById(buttonID);
        btn.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                showFragment(btn);
            }
        });
    }

    public void showFragment(View v) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        switch (v.getId()) {
            case R.id.btnConfig:
                if (configFragment == null) {
                    configFragment = new ConfigListFragment();
                }
                else if (configFragment.isVisible())
                    return;
                if (getCurrentEntriesInBackStack() == 0) {
                    ft.addToBackStack("mainItems");
                }
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                ft.replace(R.id.frame_cotainer, configFragment, "config");

                break;
            case R.id.btnMain:
                if (mainItemsFragment == null)
                    mainItemsFragment = new MainItemsFragment();
                if (getCurrentEntriesInBackStack() == 0)
                    return;
                else {
                    if (configFragment != null && configFragment.isVisible()) {
                        ft.detach(configFragment);
                        configFragment = null;
                    }
                    if (settingFragment != null && settingFragment.isVisible()) {
                        ft.detach(settingFragment);
                        settingFragment = null;
                    }
                    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                    removeFromContainer(ft);
                    callPopBackStack();
                    return;
                }
            case R.id.btnSetting:
                if (settingFragment == null)
                    settingFragment = new SettingFragment();
                else if (settingFragment.isVisible())
                    return;
                if (getCurrentEntriesInBackStack() == 0) {
                    ft.addToBackStack("mainItems");
                }
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                ft.replace(R.id.frame_cotainer, settingFragment, "setting");
                break;
            default:
                break;
        }

        ft.commit();
    }

    private int getCurrentEntriesInBackStack() {
        FragmentManager fm = getSupportFragmentManager();
        return fm.getBackStackEntryCount();
    }

    private boolean callPopBackStack() {
        FragmentManager fm = getSupportFragmentManager();

        boolean result = fm.popBackStackImmediate();
        return result;
    }

    private void removeFromContainer(FragmentTransaction ft) {
        if (configFragment != null && configFragment.isVisible()) {
            ft.detach(configFragment);
            configFragment = null;
        }
        if (settingFragment != null && settingFragment.isVisible()) {
            ft.detach(settingFragment);
            settingFragment = null;
        }
        ft.commit();
    }

    public static class ConfigListFragment extends Fragment {

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.layout_config, container, false);
            return v;
        }
    }

    public static class SettingFragment extends Fragment {
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.layout_setting, container, false);
            return v;
        }

    }

    public static class MainItemsFragment extends Fragment {

        private MyPagerAdapter adapter;
        private ViewPager viewpager;
        private PageIndicator mIndicator;
        View rootView;

        private class setAdapterTask extends AsyncTask<Void, Void, Void> {
            protected Void doInBackground(Void... params) {
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                viewpager.setAdapter(adapter);
                mIndicator = (CirclePageIndicator) rootView.findViewById(R.id.indicator);
                mIndicator.setViewPager(viewpager);

                viewpager.setCurrentItem(0);

            }
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            rootView = inflater.inflate(R.layout.mainscreen_layout, container, false);

            adapter = new MyPagerAdapter(getFragmentManager());
            viewpager = (ViewPager) rootView.findViewById(R.id.myviewpager);
            new setAdapterTask().execute();
            return rootView;
        }

    }

    public static class MyPagerAdapter extends FragmentPagerAdapter {

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int index) {
            if (index == 0) {
                return new MainFragment1();
            }
            else {
                return new MainFragment2();
            }
        }

        @Override
        public int getCount() {
            return 2;
        }
    }

    @Override
    public void onBackPressed() {

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        removeFromContainer(ft);
        if (fm.popBackStackImmediate()) {
            return;
        }

        else {

            AlertDialog.Builder dlg = new AlertDialog.Builder(MainActivity.this);
            dlg.setTitle("Confirm Exit");
            dlg.setMessage("Do you want to exit?").setCancelable(false).setPositiveButton("OK", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    MainActivity.this.finish();
                }

            }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

            AlertDialog alertDlg = dlg.create();
            alertDlg.show();
        }
    }

}
like image 1000
zungnv Avatar asked Dec 14 '12 04:12

zungnv


1 Answers

It looks like you are using one of the old hacks in order to embed fragments. I would suggest that you first upgrade to the latest Android Support Library, ie. Release 11 . Then have a look at how to use the Child FragmentManager http://developer.android.com/reference/android/support/v4/app/Fragment.html#getChildFragmentManager()

I have an example on github on how to nest fragments with a viewpager.
https://github.com/marsucsb/nested-fragments

like image 170
Marco RS Avatar answered Oct 14 '22 04:10

Marco RS