Android 在 Fragment 上实施 onBackPress 导致禁用退出应用程序
Android implementing onBackPress on Fragment cause of disable exit from application
在我的应用程序中,我有一些片段,我可以通过单击 phone 上的返回退出应用程序而没有问题,但是当我在其上实现 onBackPress
时,我无法退出应用程序
我的代码:
@Override
public void onResume() {
super.onResume();
if (getView() == null) {
return;
}
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) {
if (slider_call_phones.isOpened()) {
slider_call_phones.closeLayer(true);
}
return true;
}
return false;
}
});
}
我想在片段而不是活动
上处理onBackPressed
您应该按以下方式调用 onBackPressed() 以退出应用程序:
public void onBackPressed(){
finishAffinity();
}
这是我的做法,
- 创建一个可以在任何 class 中接收
onBackPressed()
的接口
实现它,如果它正在处理该方法,则 return 为真,否则为假。这将确保您的应用程序在 return false 时退出。
- 在您的
Activity
中创建这些接口的堆栈,然后将任何此类接口添加到其中。
- 覆盖 activity 中的
onBackPressed()
,然后在任何时候调用它,从堆栈中获取一个侦听器,如果 return 为真,则调用它自己的 onBackPressed()
。如果它 return 为假,则它不会处理 onBackPressed()
,因此 Activity 可以接管并删除片段或退出应用程序。
这是一个示例实现。
在你的Activity
public class MyActivity extends Activity {
//a stack of OnBackPressedListeners, stack one when you want it to receive onBackPressed() from
//this activity.
//PS used stack so that by LIFO, the last listener would be the first to be called.
private Stack<OnBackPressedListener> onBackPressedListeners = new Stack<>();
@Override
public void onBackPressed() {
if (!onBackPressedListeners.isEmpty()) {
if (onBackPressedListeners.peek().onBackPressed()) //if interface is handling onBackPressed(), return. Otherwise super would be called below.
return;
}
//if no listeners, then do super. This would ensure natural behaviour such as closing the app or popping a fragment when no listeners are using onBackPressed()
super.onBackPressed();
}
//listener interface
public static interface OnBackPressedListener {
/**
* @return true if you're handling onBackPressed, false otherwise to let super.onBackPressed() take over
*/
public boolean onBackPressed();
}
public void addOnBackPressedListener(OnBackPressedListener listener) {
onBackPressedListeners.add(listener);
}
public void removeOnBackPressedListener(OnBackPressedListener listener) {
onBackPressedListeners.remove(listener);
}
}
在你的片段中
//implement OnBackPressedListener in your fragment.
public class MyFragment extends Fragment implements OnBackPressedListener {
//find somewhere to add the listener to your Activity, most likely in onCreateView(...)
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
...
((MyActivity)getActivity()).addOnBackPressedListener(this);
...
return view;
}
//overide onBackPressed(), then return true if you're handling the onBackPressed(), false otherwise.
@Override
public boolean onBackPressed() {
if (slider_call_phones.isOpened()) {
slider_call_phones.closeLayer(true);
return true;
}
return false;
}
//lastly remember to remove the listener when your fragment is destroyed, so that it stops receiving callbacks,
//if you don't do this, you might get a NullPointerException.
@Override
public void onDestroy() {
super.onDestroy();
((MyActivity)getActivity()).removeOnBackPressedListener(this);
}
}
我主要在我的 Android 应用程序中使用单个 Activity
和大量 Fragment
,这正是我解决您遇到的此类问题的方法,例如如果在按下后退按钮时抽屉处于打开状态,则关闭 Fragment 中的抽屉;如果抽屉已关闭,则退出应用程序。
在我的应用程序中,我有一些片段,我可以通过单击 phone 上的返回退出应用程序而没有问题,但是当我在其上实现 onBackPress
时,我无法退出应用程序
我的代码:
@Override
public void onResume() {
super.onResume();
if (getView() == null) {
return;
}
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) {
if (slider_call_phones.isOpened()) {
slider_call_phones.closeLayer(true);
}
return true;
}
return false;
}
});
}
我想在片段而不是活动
上处理onBackPressed
您应该按以下方式调用 onBackPressed() 以退出应用程序:
public void onBackPressed(){
finishAffinity();
}
这是我的做法,
- 创建一个可以在任何 class 中接收
onBackPressed()
的接口 实现它,如果它正在处理该方法,则 return 为真,否则为假。这将确保您的应用程序在 return false 时退出。 - 在您的
Activity
中创建这些接口的堆栈,然后将任何此类接口添加到其中。 - 覆盖 activity 中的
onBackPressed()
,然后在任何时候调用它,从堆栈中获取一个侦听器,如果 return 为真,则调用它自己的onBackPressed()
。如果它 return 为假,则它不会处理onBackPressed()
,因此 Activity 可以接管并删除片段或退出应用程序。
这是一个示例实现。
在你的Activity
public class MyActivity extends Activity {
//a stack of OnBackPressedListeners, stack one when you want it to receive onBackPressed() from
//this activity.
//PS used stack so that by LIFO, the last listener would be the first to be called.
private Stack<OnBackPressedListener> onBackPressedListeners = new Stack<>();
@Override
public void onBackPressed() {
if (!onBackPressedListeners.isEmpty()) {
if (onBackPressedListeners.peek().onBackPressed()) //if interface is handling onBackPressed(), return. Otherwise super would be called below.
return;
}
//if no listeners, then do super. This would ensure natural behaviour such as closing the app or popping a fragment when no listeners are using onBackPressed()
super.onBackPressed();
}
//listener interface
public static interface OnBackPressedListener {
/**
* @return true if you're handling onBackPressed, false otherwise to let super.onBackPressed() take over
*/
public boolean onBackPressed();
}
public void addOnBackPressedListener(OnBackPressedListener listener) {
onBackPressedListeners.add(listener);
}
public void removeOnBackPressedListener(OnBackPressedListener listener) {
onBackPressedListeners.remove(listener);
}
}
在你的片段中
//implement OnBackPressedListener in your fragment.
public class MyFragment extends Fragment implements OnBackPressedListener {
//find somewhere to add the listener to your Activity, most likely in onCreateView(...)
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
...
((MyActivity)getActivity()).addOnBackPressedListener(this);
...
return view;
}
//overide onBackPressed(), then return true if you're handling the onBackPressed(), false otherwise.
@Override
public boolean onBackPressed() {
if (slider_call_phones.isOpened()) {
slider_call_phones.closeLayer(true);
return true;
}
return false;
}
//lastly remember to remove the listener when your fragment is destroyed, so that it stops receiving callbacks,
//if you don't do this, you might get a NullPointerException.
@Override
public void onDestroy() {
super.onDestroy();
((MyActivity)getActivity()).removeOnBackPressedListener(this);
}
}
我主要在我的 Android 应用程序中使用单个 Activity
和大量 Fragment
,这正是我解决您遇到的此类问题的方法,例如如果在按下后退按钮时抽屉处于打开状态,则关闭 Fragment 中的抽屉;如果抽屉已关闭,则退出应用程序。