2

I have problem: A Fragment is not reattached to its hosting ViewPager after returning from another fragment by using popBackStack.

One Activity hosting a Fragment whose layout holds a ViewPager. The ViewPager is populated by a FragmentStateViewPagerAdapter. The Fragment hosted inside the pager can open sub page lists, containing a new set of pages. All works fine as long as the back button is not pressed. As soon as the user closes one of the sub Page the previous Page is recreated, but without the Page that was displayed previously (Empty page with whiteblank page). I have searching but still not resolve my problem.

Full Code of TestProject can be found on Github

MainActivity:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val ft = supportFragmentManager.beginTransaction()
        ft.add(R.id.frameLayout, HomeFragment.newInstance())
        ft.commit()
    }
}

HomeFragment:

public class HomeFragment extends Fragment {


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

        TabLayout tabLayout = v.findViewById(R.id.tabLayout);

        ViewPager viewPager = v.findViewById(R.id.viewPager);
        VPAdapter adapter = new VPAdapter(getFragmentManager());

        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);

        return v;
    }

    public static Fragment newInstance() {
        return new HomeFragment();
    }
}

VPAdapter:

public class VPAdapter extends FragmentStatePagerAdapter{


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

    @Override
    public Fragment getItem(int position) {
        return TabFragment.newInstance(position);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "TAB " + position;
    }

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

TabFragment:

public class TabFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e("TAB", "onCreate");
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.e("TAB", "onCreateView");
        return inflater.inflate(R.layout.fragment_tab, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        Bundle args = getArguments();
        if (args != null) {
            int tabIndex = args.getInt("tab_index", 0);
            TextView tv = view.findViewById(R.id.textView);
            tv.setText(String.format(Locale.getDefault(), "TAB FRAGMENT INDEX %d", tabIndex));
        }

        Button button = view.findViewById(R.id.button);
        button.setText("Open Next Fragment");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.frameLayout, LastFragment.newInstance());
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("TAB", "onDestroy");
    }

    public static Fragment newInstance(int index) {
        Bundle args = new Bundle();
        args.putInt("tab_index", index);
        TabFragment tab = new TabFragment();
        tab.setArguments(args);
        return tab;
    }
}

LastFragment:

public class LastFragment extends Fragment {

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

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        view.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getFragmentManager().popBackStack();
            }
        });
    }

    public static Fragment newInstance() {
        return new LastFragment();
    }
}
Sinh Phan
  • 1,180
  • 3
  • 16
  • 36
  • Use getChildFragmentManager() https://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager() – AbhayBohra Dec 27 '17 at 05:07

1 Answers1

3

You have to Use getChildFragmentManager() For Viewpager to adapt Popback Feature.

VPAdapter adapter = new VPAdapter(getChildFragmentManager());

You Can Refer this Documentation on ChildFragmentManager()

Tomin B Azhakathu
  • 2,656
  • 1
  • 19
  • 28
  • 1
    You also needed to update TabFragment with `getActivity().getSupportFragmentManager().beginTransaction();` for getting FragmentManager of activity instead of parent's childFragmentManager – Archit Sureja Dec 27 '17 at 06:04