我现在有一个包含片段的活动
[1],[2],[3],[4]
如果按下按钮[3],可以将其重定向到[4]
我想实现后退按钮,如下所示..
在[4]按下时,返回[3]
当按下[3]时,返回[2]
当按下[1]时,活动结束();
当涉及到当前的实现时,它完成活动而不是弹出Fragment。你能告诉我我应该做什么或记住什么?
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if( keyCode==KeyEvent.KEYCODE_BACK)
{
finish();
}
return super.onKeyDown(keyCode, event);
}
答案 0 :(得分:87)
这对我有用。
- 从活动中调用新片段时添加.addToBackStack(null)。
FragmentTransaction mFragmentTransaction = getFragmentManager()
.beginTransaction();
....
mFragmentTransaction.addToBackStack(null);
- 将onBackPressed()添加到您的活动
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
getFragmentManager().popBackStack();
}
}
答案 1 :(得分:50)
最简单的方式:
<强>的onResume()强>:
@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's click listener
Toast.makeText(getActivity(), "Back press", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
}
修改1 :如果片段有EditText
。
private EditText editText;
<强> onCreateView()强>:
editText = (EditText) rootView.findViewById(R.id.editText);
<强>的onResume()强>:
@Override
public void onResume() {
super.onResume();
editText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
editText.clearFocus();
}
return false;
}
});
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's click listener
Toast.makeText(getActivity(), "Back press", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
}
注意:如果片段中有 EditText ,它将会有效。
完成强>
答案 2 :(得分:8)
这对我来说是一个有效的解决方案:
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// DO WHAT YOU WANT ON BACK PRESSED
return true;
}
return false;
}
});
修改:您可以将getView()
的对话框替换为片段。
答案 3 :(得分:7)
你可以用这个..为我工作..
当按下后退时,似乎没有从视图中删除片段[3],所以你必须手动完成!
首先,不要使用replace(),而是使用remove并单独添加。似乎replace()无法正常工作。
下一部分是重写onKeyDown方法,并在每次按下后退按钮时删除当前片段。
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
if (getSupportFragmentManager().getBackStackEntryCount() == 0)
{
this.finish();
return false;
}
else
{
getSupportFragmentManager().popBackStack();
removeCurrentFragment();
return false;
}
}
return super.onKeyDown(keyCode, event);
}
public void removeCurrentFragment()
{
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.f_id);
}
答案 4 :(得分:5)
尝试这个简单的解决方案:
在你的活动中实现onBackPressed
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
} else {
finish();
}
}
如果您想在每次背面按下弹出顶部片段,这将有效。 注意: - 向活动添加片段时,请务必将事务添加到后台,以便工作
答案 5 :(得分:4)
更好的解决方案可能是遵循设计模式,以便后退按钮事件从活动片段传播到主机Activity。所以,它就像..如果其中一个活动片段消耗了背压,活动就不会对它采取行动,反之亦然。
一种方法是让你的所有片段扩展一个基本片段,该片段具有抽象的布尔值onBackPressed()&#39;方法
@Override
public boolean onBackPressed() {
if(some_condition)
// Do something
return true; //Back press consumed.
} else {
// Back-press not consumed. Let Activity handle it
return false;
}
}
跟踪活动内部的活动片段,并在其内部的onBackPressed回调中写下这样的内容
@Override
public void onBackPressed() {
if(!activeFragment.onBackPressed())
super.onBackPressed();
}
}
这篇文章详细描述了这种模式
答案 6 :(得分:4)
在这种情况下我做的是从Activity:
实现onBackPressed()函数@Override
public void onBackPressed() {
super.onBackPressed();
FragmentManager fm = getSupportFragmentManager();
MyFragment myFragment = (MyFragment) fm.findFragmentById(R.id.my_fragment);
if((myFragmen.isVisible()){
//Do what you want to do
}
}
这对你有用。
答案 7 :(得分:4)
我解决问题的方式我相信它也会对你有所帮助:
1.如果你的片段中没有任何编辑文本框,你可以使用下面的代码
这里的MainHomeFragment是主要片段(当我从第二个片段按下后退按钮时,它会带我太MainHomeFragment)
@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){
MainHomeFragment mainHomeFragment = new SupplierHomeFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, mainHomeFragment);
fragmentTransaction.commit();
return true;
}
return false;
}
}); }
2.如果你有另一个名为Somefragment的片段并且它有Edit文本框,那么你就可以这样做。
private EditText editText;
然后在,
onCreateView():
editText = (EditText) view.findViewById(R.id.editText);
然后覆盖OnResume,
@Override
public void onResume() {
super.onResume();
editText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
editTextOFS.clearFocus();
getView().requestFocus();
}
return false;
}
});
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){
MainHomeFragment mainHomeFragment = new SupplierHomeFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, mainHomeFragment);
fragmentTransaction.commit();
return true;
}
return false;
}
});
}
所有人(amitamie.com):-); - )
答案 8 :(得分:3)
您可以在基本getFragmentManager().popBackStack()
中使用Fragment
返回。
答案 9 :(得分:2)
您还需要检查Action_Down或Action_UP事件。如果你不检查那么onKey()方法会调用2次。
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Toast.makeText(getActivity(), "Back Pressed", Toast.LENGTH_SHORT).show();
return true;
}
}
return false;
}
});
为我工作得非常好。
答案 10 :(得分:2)
您可以在onCreateView中使用它,可以使用事务或替换
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
//what you want to do
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
答案 11 :(得分:2)
如果您在片段中使用webview而不是在onCreateView方法中使用它
webView.setOnKeyListener(new View.OnKeyListener(){
@Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if((i==KeyEvent.KEYCODE_BACK)&& webView.canGoBack()){
webView.goBack();
return true;
}
return false;
}
});
并导入此类
import android.view.KeyEvent;
答案 12 :(得分:1)
请务必添加以下内容:
if (event.getAction()!=KeyEvent.ACTION_DOWN)
return true;
在onKey代码块中,以避免事件调用两次。
答案 13 :(得分:1)
好吧,我终于找到了一个好的解决方案。
在容纳片段的活动的onCreate()中,添加一个backstack更改侦听器,如下所示:
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
List<Fragment> f = fragmentManager.getFragments();
Fragment frag = f.get(0);
currentFragment = frag.getClass().getSimpleName();
}
});
(还添加了我的fragmenManager声明为全局) 现在,每次更改片段时,当前片段字符串将成为当前片段的名称。然后,在活动onBackPressed()中,您可以这样控制后退按钮的操作:
@Override
public void onBackPressed() {
switch (currentFragment) {
case "FragmentOne":
// your code here (Maybe dialog)
return;
case "FragmentTwo":
// your code here
return;
default:
fragmentManager.popBackStack();
// default action for any other fragment (return to previous)
}
}
我可以确认此方法对我有用。
答案 14 :(得分:0)
我使用一种方法来改变代码后面的片段
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit).replace(R.id.content_frame, mContent, mContent.getClass().getSimpleName()).addToBackStack(null)
.commit();
以及后退按钮。
@Override
public void onBackPressed() {
// note: you can also use 'getSupportFragmentManager()'
FragmentManager mgr = getSupportFragmentManager();
if (mgr.getBackStackEntryCount() == 1) {
// No backstack to pop, so calling super
finish();
} else {
mgr.popBackStack();
}
}
需要注意的重要一点是我使用1来检查getBackStackEntryCount这是因为如果你不使用它并且使用0,则用户看不到最后一个后退按钮。
答案 15 :(得分:0)
(在Kotlin中)使用此
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// in here you can do logic when backPress is clicked
}
})
我认为这是最优雅的方式
答案 16 :(得分:0)
试试这个,它对我有帮助:)
@Override
public void onResume() { //Pressed return button - returns to the results menu
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) {
/*Here your code*/
return true;
}
return false;
}
});
}