Search code examples
androidandroid-fragmentsandroid-viewpagerandroid-listfragment

Create new Fragment from a Fragment which is part of ViewPager


I've seen many questions that seemed relevant, but I have failed to found the one that is exactly what I'm looking for.

I have an App, with a ViewPager in MainActivity. one of the Fragments in the ViewPager is a ListFragment. I want to enable a creation of new Fragment when the user clicks a List item, using onListItemClick function. The new Fragment will replace the ViewPager, and will display its layout and data. I also want to allows clicking the Back button, which will return the User to the previous state of the PageViewer.

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
        StationDescriptionFragment newFragment = new StationDescriptionFragment();
        Bundle args = new Bundle();
        args.putString(StationDescriptionFragment.ARG_DESCRIPTION, this.stationsList.get(position).getDescription());
        newFragment.setArguments(args);
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, newFragment);
        transaction.addToBackStack(null);
        transaction.commit();
        getListView().setItemChecked(position, true);
    }

This code is inside the Fragment which is part of the ViewPager. This code ends and than the app crashes right after this function ends. I know for sure that this function ends.

The crash is:

FragmentManagerImpl.throwException(RuntimeException) line: 462

The StationDescriptionFragment class:

public class StationDescriptionFragment extends Fragment {
    final static String ARG_DESCRIPTION = "description";
    String mCurrentDescription = "";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            mCurrentDescription = savedInstanceState.getString(ARG_DESCRIPTION);
        }
        return inflater.inflate(R.layout.description_view, container, false);
    }

    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        updateDescription("Some Description");
    }

    public void updateDescription(String description) {
        TextView desc = (TextView) getActivity().findViewById(R.id.description);
        desc.setText(description);
        mCurrentDescription = description;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(ARG_DESCRIPTION, mCurrentDescription);
    }
}

description_view.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/description"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:textSize="18sp" />

Any help will be much appreciated. Thanks.


Solution

  • The new Fragment will replace the ViewPager, and will display its layout and data. I also want to allows clicking the Back button, which will return the User to the previous state of the PageViewer.

    If you want to replace the ViewPager(which I assume is in another fragment) along with its page fragments then use the normal FragmentManager and not the one returned by getChildFragmentManager() which is targeted at implementing nested fragments. getChildFragmentManager() will look for that id(to put the new fragment) in the current fragment's view and I assume R.id.fragment_container is the id of the container that holds the fragment with the ViewPager:

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
            getListView().setItemChecked(position, true); // call this before the transaction 
            StationDescriptionFragment newFragment = new StationDescriptionFragment();
            Bundle args = new Bundle();
            args.putString(StationDescriptionFragment.ARG_DESCRIPTION, this.stationsList.get(position).getDescription());
            newFragment.setArguments(args);
            FragmentTransaction transaction = getFragmentManager().beginTransaction();
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
    }