ViewPager:从子片段导航回父片段将关闭应用程序 [英] ViewPager : Navigating Back to Parent Fragment From Child Fragment Closes The Application
问题描述
我正在 ViewPager
中实现嵌套片段。在执行 addToBackStack()
之后,通过替换父片段中的子片段来执行事务时,可以看到下面的视图。但是当我按下后退按钮并且代码到达 MainActivity
的 onBackPressed()
方法时,我注意到堆栈大小为1,我成功弹出 Fragment
。问题现在开始
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
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();
}
}
}
父片段
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
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
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];
}
}
推荐答案
如果您使用 FragmentTransaction.addToBackStack()
,后退按钮将自动为您处理。
If you use FragmentTransaction.addToBackStack()
, the back button is handled automatically for you.
执行此操作时:
@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.
在<$ c中替换 onBackPressed()
方法$ c>活动与此:
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();
}
}
这篇关于ViewPager:从子片段导航回父片段将关闭应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!