【问题标题】:ViewPager : Navigating Back to Parent Fragment From Child Fragment Closes The ApplicationViewPager:从子片段导航回父片段关闭应用程序
【发布时间】:2015-07-15 08:51:57
【问题描述】:

我在ViewPager 中实现嵌套片段。当我在执行addToBackStack() 后通过替换父片段中的子片段来执行事务时,我能够看到如下所示的视图。但是当我按下返回按钮并且代码到达MainActivity 的onBackPressed() 方法时,我注意到堆栈大小为1,并且我成功弹出了Fragment。问题从现在开始

我的应用关闭,在短时间内,我看到我的子片段关闭,然后应用关闭。

主活动

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();
        }

    }
}

父片段

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;
    }
}

子片段

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];
    }
}

【问题讨论】:

    标签: android android-fragments android-viewpager android-nested-fragment


    【解决方案1】:

    如果您使用FragmentTransaction.addToBackStack(),则会自动为您处理后退按钮。

    当你这样做时:

    @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();
        }
    }
    

    您基本上是在弹出堆栈两次,这就是您的应用程序退出的原因。

    将Activity 中的onBackPressed() 方法替换为:

    @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();
        }
    }
    

    【讨论】:

    • 我刚刚实现了你所说的。虽然没有工作。我现在观察到的唯一区别是片段和活动同时关闭。现在他们之间没有差距了..
    • 通过删除 super.onBackPressed(); 行解决了我的问题;
    • 如果您不想破坏后退按钮,您仍然应该在某个时候致电super.onBackPressed()。我已经在这方面编辑了我的答案
    • 是的,当我在堆栈中没有任何东西时,我在 else 块中调用了它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多