我现在有一个包含碎片的活动
[1] , [2] , [3] , [4]
如果按下按钮 [3] ,它可以重定向到 [4]
我想实现后退按钮,如下所示..
在 [4] 按回时,返回 [3]
在 [3] 按回时,返回 [2]
在 [1] 处按回车时,活动结束();
说到现在的实现,是完成activity,而不是弹出fragment。你能告诉我我应该做什么或记住什么吗?
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if( keyCode==KeyEvent.KEYCODE_BACK)
{
finish();
}
return super.onKeyDown(keyCode, event);
}
这对我有用。
-从活动中调用新片段时添加 .addToBackStack(null)。
FragmentTransaction mFragmentTransaction = getFragmentManager()
.beginTransaction();
....
mFragmentTransaction.addToBackStack(null);
-将 onBackPressed() 添加到您的活动中
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
getFragmentManager().popBackStack();
}
}
有史以来最简单的方法:
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,它将起作用。
完成
这对我来说是一个可行的解决方案:
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()
替换对话片段。
试试这个简单的解决方案:
在你的活动中实现 onBackPressed
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
} else {
finish();
}
}
如果你想在每次向后按时弹出顶部片段,这将起作用。 注意:- 在将片段添加到活动时,始终将事务添加到后台堆栈以使其工作
在包含片段的活动中的 onCreate() 中添加一个后台更改侦听器,如下所示:
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
List<Fragment> f = fragmentManager.getFragments();
Fragment frag = f.get(0);
currentFragment = frag.getClass().getSimpleName();
}
});
(注:我的 fragmentManager 被声明为全局的) 现在每次更改片段时,currentFragment String 都会成为当前片段的名称。然后在 onBackPressed() 活动中,您可以这样控制后退按钮的操作:
@Override
public void onBackPressed() {
switch (currentFragment) {
case "FragmentOne":
// your code here
return;
case "FragmentTwo":
// your code here
return;
default:
fragmentManager.popBackStack();
// default action for any other fragment (return to previous)
}
}
我可以确认这个方法对我有用。
更新:Kotlin
override fun onBackPressed() {
when(supportFragmentManager.fragments[0].javaClass.simpleName){
"FragmentOne" -> doActionOne()
"FragmentTwo" -> doActionTwo()
else -> supportFragmentManager.popBackStack()
}
}
我解决问题的方式我相信它也会帮助你:
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 的片段,并且它有编辑文本框,那么你可以通过这种方式来完成。
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) :-) ;-)
更好的解决方案可能是遵循一种设计模式,使后退按钮按下事件从活动片段向下传播到宿主活动。所以,这就像..如果一个活动片段消耗了后压,活动就不会对其采取行动,反之亦然。
一种方法是让所有片段扩展一个基本片段,该片段具有抽象的“boolean onBackPressed()”方法。
@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;
}
}
跟踪 Activity 中的活动片段以及在它的 onBackPressed 回调中写这样的东西
@Override
public void onBackPressed() {
if(!activeFragment.onBackPressed())
super.onBackPressed();
}
}
这篇文章详细描述了这种模式
我在这种情况下所做的是从 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
}
}
这对你也有用。
如果你在片段中使用 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;
您可以在基本
getFragmentManager().popBackStack()
中使用Fragment
返回。
您还需要检查 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;
}
});
对我来说工作得很好。
你可以在onCreateView中使用这个,你可以使用事务或替换
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
//what you want to do
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
确保添加以下内容:
if (event.getAction()!=KeyEvent.ACTION_DOWN)
return true;
在 onKey 代码块中避免事件调用两次。
我使用一种方法来更改它具有以下代码的片段
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 用户看不到最后一个后退按钮。
使用这个(在科特林中)
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// in here you can do logic when backPress is clicked
}
})
我认为这是最优雅的方式
试试这个,它帮助了我:)
@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;
}
});
}
只需将其粘贴到您的活动主目录中
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
} else {
finish();
}
}
Fragment Pressing Back Button - 我们正在使用 popBackStack() 函数。
In Kotlin - 在您的活动中编写代码
override fun onBackPressed() {
super.onBackPressed()
supportFragmentManager.popBackStack();
}