在 Android 中使用片段时处理后按
Posted
技术标签:
【中文标题】在 Android 中使用片段时处理后按【英文标题】:Handling back press when using fragments in Android 【发布时间】:2014-04-28 11:28:14 【问题描述】:我在我的应用程序中使用带有导航抽屉的 android 滑动菜单,并且在应用程序中使用片段而不是活动。 当我打开抽屉时,单击一个出现片段的项目。我使用以下代码从一个片段移动到另一个片段:
Fragment fragment = null;
fragment = new GalleryFragment(selectetdMainMenu.getCategoryID());
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.addToBackStack("menuFrag");
ft.add(R.id.frame_container, fragment, "menuFrag");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
通过这种方式,我可以从一个片段转到另一个片段,但在按下后退按钮时我无法到达前一个片段。我设法想出了这段代码来处理初始化抽屉的 MainActivity 中的后按:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
super.onKeyDown(keyCode, event);
if (keyCode == KeyEvent.KEYCODE_BACK)
Fragment fragment_byTag = fragmentManager.findFragmentByTag("menuFrag");
Fragment menuFragment_by_tag = fragmentManager.findFragmentByTag("galleryFrag");
Fragment commentsFrag_by_tag = fragmentManager.findFragmentByTag("commentsFrag");
Fragment dealDetail = fragmentManager.findFragmentByTag("promoFrag");
if(commentsFrag_by_tag != null)
if (commentsFrag_by_tag.isVisible())
Log.e("comments back ", " clicked");
//menuDetailsFrag.onBackPressed();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().remove(commentsFrag_by_tag).commit();
fragmentManager.beginTransaction().show(menuFragment_by_tag).commit();
else if(menuFragment_by_tag.isVisible())
Log.e("menu back ", " clicked");
menuDetailsFrag.onBackPressed();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().remove(menuFragment_by_tag).commit();
fragmentManager.beginTransaction().show(fragment_byTag).commit();
return false;
这有时有效,但大部分时间都失败了。如果可以显示更好的导航方式,我将不胜感激。
【问题讨论】:
看看这个 .. ***.com/questions/22552653/… add thisft.addToBackStack(null);ft.commit();
将片段添加到后台堆栈并弹出它们。 ***.com/questions/22550420/…
@Raghunandan。我找到的最简单的解决方案是你的。
我知道这篇文章很旧,但请看我的回答:***.com/a/45430033/3999826
【参考方案1】:
我通常将onKeyListener
设置为onResume
中的View
。据我所知,您必须注意在View
上设置setFocusableInTouchMode()
和requestFocus
。
这是我用于此目的的示例:
@Override
public void onResume()
super.onResume();
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener()
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK)
// handle back button
return true;
return false;
);
【讨论】:
我在哪里放置此代码?片段或主要活动> 这行得通。我添加了 getActivity().getSupportFragmentManager().popBackStack();处理后按。 onresume 中有 keyevent 的原因是什么? @super-qua,片段的绝佳解决方案 如果您在片段中有一个可以获得焦点的子视图,这将停止工作。例如,如果您在片段中有“列表状态”和“编辑状态”,则进入其中包含EditText
的“编辑状态”,选择EditText
,主视图将失去焦点并且onKey()
将停止运行,除非您手动重新获得基本视图的焦点。【参考方案2】:
试试这些方法。对我来说,最有用的解决方案如下:
在 MainActivity 中:
getSupportFragmentManager().beginTransaction().replace(R.id.gif_contents, gifPageTwoFragment, "gifPageTwoFragment").addToBackStack("gifPageTwoFragment").commit();
在 GifPageTwoFragment 中:
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener()
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK)
Log.e("gif--","fragment back key is clicked");
getActivity().getSupportFragmentManager().popBackStack("gifPageTwoFragment", FragmentManager.POP_BACK_STACK_INCLUSIVE);
return true;
return false;
);
【讨论】:
【参考方案3】:在您的 oncreateView() 方法中,您需要编写此代码,在 KEYCODE_BACk 条件下,您可以编写任何您想要的功能
View v = inflater.inflate(R.layout.xyz, container, false);
//Back pressed Logic for fragment
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener(new View.OnKeyListener()
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
if (event.getAction() == KeyEvent.ACTION_DOWN)
if (keyCode == KeyEvent.KEYCODE_BACK)
getActivity().finish();
Intent intent = new Intent(getActivity(), MainActivity.class);
startActivity(intent);
return true;
return false;
);
【讨论】:
这对我来说是完美的【参考方案4】: view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(new View.OnKeyListener()
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
if (keyCode == KeyEvent.KEYCODE_BACK)
Fragment NameofFragment = new NameofFragment;
FragmentTransaction transaction=getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container,NameofFragment);
transaction.commit();
return true;
return false;
);
return view;
【讨论】:
【参考方案5】:使用这个(在 kotlin 中)
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true)
override fun handleOnBackPressed()
// in here you can do logic when backPress is clicked
)
我认为这是最优雅的方式
【讨论】:
以上是关于在 Android 中使用片段时处理后按的主要内容,如果未能解决你的问题,请参考以下文章