简体   繁体   中英

ViewPager : Navigating Back to Parent Fragment From Child Fragment Closes The Application

I am implementing nested fragments in a ViewPager . When I perform the transaction by replacing the child fragment in the parent fragment after executing addToBackStack() , I am able to see the view shown below. But when I press back button and the code reaches the MainActivity 's onBackPressed() method, I notice the stack size is 1, and I successfully popout the Fragment . The problem starts now

My app closes and for a brief amount of time, I see my child fragment closing and then the app closing.

在此处输入图片说明

MainActivity

public class MainActivity extends FragmentActivity implements FragmentCommunicationListener {

    ViewPager viewPager;
    PagerAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //createTabs();
        viewPager = (ViewPager) findViewById(R.id.pager);
        Fragment[] fragments = new Fragment[]{
                new ViewStudentsFragment(),
                new AddStudentFragment()
        };
        pagerAdapter = new PagerAdapter(getSupportFragmentManager(), this, fragments);
        viewPager.setAdapter(pagerAdapter);
    }

    @Override
    public void passMsg(Fragment fragment, Bundle msg) {

        int currentItem = viewPager.getCurrentItem();
        Fragment targetFragment;
        if (currentItem == 0) {
            targetFragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 1);
            ((AddStudentFragment) targetFragment).renderData(msg);
            viewPager.setCurrentItem(1);
        } else {
            targetFragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 0);
            ((ViewStudentsFragment) targetFragment).updateList(msg,viewPager);
            viewPager.setCurrentItem(0);
        }
    }

    @Override
    public void onBackPressed() {
        ViewStudentsFragment fragment = (ViewStudentsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 0);
        super.onBackPressed();
        if (fragment.getChildFragmentManager().getBackStackEntryCount() != 0) {           
            fragment.getChildFragmentManager().popBackStack();
        }

    }
}

Parent Fragment

public class ViewStudentsFragment extends Fragment {

    ArrayList<Student> studentList = new ArrayList<Student>();
    ListView list;
    ListViewAdapter listAdapter;
    GridView grid;
    FragmentCommunicationListener fragComm = null;
    int resIdView, resIdSort;
    GridViewAdapter gridAdapter;
    static ImageButton toggleView, toggleSort;
    View view;
    ViewPager viewPager=null;
    public ViewStudentsFragment() {

    }

    private static ViewStudentsFragment viewStudentsFragment;
    FragmentTransaction transaction;
    Fragment details ;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_view_students, container, false);
        toggleView = (ImageButton) view.findViewById(R.id.viewImageButton);
        toggleSort = (ImageButton) view.findViewById(R.id.sortImageButton);
        transaction= getChildFragmentManager().beginTransaction();
        view.findViewById(R.id.container).setVisibility(View.GONE);
        ...

        toggleView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ...
            }

        });

        toggleSort.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               ...
            }
        });

        registerForContextMenu(list);
        registerForContextMenu(grid);
        return view;
    }

    public void updateList(Bundle bundle,ViewPager vp) {
        viewPager=vp;
        ...

        }
        listAdapter.notifyDataSetChanged();
        gridAdapter.notifyDataSetChanged();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity instanceof FragmentCommunicationListener) {
            fragComm = (FragmentCommunicationListener) activity;
        } else {
            throw new ClassCastException();
        }
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {

        ...
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        ...
        switch (menuItemIndex) {
            case Constant.VIEW_STUDENT_DETAIL:
                bundle.putSerializable("viewField", student);                                                          view.findViewById(R.id.container).setVisibility(View.VISIBLE);
                transaction.addToBackStack(null);
                details = new Details();
                transaction.replace(R.id.container, details, "task");
                transaction.commit();
                details.setArguments(bundle);
                break;
            ...
            default:
        }
        listAdapter.setStudentList(studentList);
        gridAdapter.setStudentList(studentList);
        listAdapter.notifyDataSetChanged();
        gridAdapter.notifyDataSetChanged();
        return true;
    }
}

ChildFragment

public class Details extends Fragment {
    View view;
    static Details details;
    Context context;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        context=container.getContext();
        Bundle bundle = getArguments();
        view=inflater.inflate(R.layout.display_details, container, false);
        ...
        return view;
    }
    @Override
    public void onDetach() {
        super.onDetach();
        view.findViewById(R.id.displayDetails).setVisibility(View.GONE);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        view.findViewById(R.id.displayDetails).setVisibility(View.GONE);
    }
    @Override
    public void setArguments(Bundle bundle) {
        super.setArguments(bundle);
    }
}

PagerAdapter

public class PagerAdapter extends FragmentPagerAdapter {


    private  String[] tabMenu;
    private    int pageCount;
    private Context context;
    private Fragment[] fragments;

    public PagerAdapter(FragmentManager fm, Context context, Fragment[] fragments) {
        super(fm);
        this.context = context;
        tabMenu = context.getResources().getStringArray(R.array.tab_menu);
        pageCount = tabMenu.length;
        this.fragments = fragments;
    }


    @Override
    public Fragment getItem(int position) {
        return fragments[position];
    }

    @Override
    public int getCount() {
        return fragments.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabMenu[position];
    }
}

If you use FragmentTransaction.addToBackStack() , the back button is handled automatically for you.

When you do this:

@Override
public void onBackPressed() {
    ViewStudentsFragment fragment = (ViewStudentsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 0);
    super.onBackPressed();
    if (fragment.getChildFragmentManager().getBackStackEntryCount() != 0) {           
        fragment.getChildFragmentManager().popBackStack();
    }
}

you are basically popping the backstack twice , which is why your application quit.

Replace the onBackPressed() method in your Activity with this:

@Override
public void onBackPressed() {
    ViewStudentsFragment fragment = (ViewStudentsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 0);

    if (fragment.getChildFragmentManager().getBackStackEntryCount() != 0) {           
        fragment.getChildFragmentManager().popBackStack();
    }
    else {
        super.onBackPressed();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM