有没有一种方法可以在 Android Fragment 中实现 onBackPressed()
,类似于我们在 Android Activity 中实现的方式?
由于 Fragment 生命周期没有 onBackPressed()
。是否有任何其他替代方法可以在 Android 3.0 片段中覆盖 onBackPressed()
?
我以这种方式解决了 Activity 中的覆盖 onBackPressed
。提交前所有的 FragmentTransaction
都是 addToBackStack
:
@Override
public void onBackPressed() {
int count = getSupportFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
//additional code
} else {
getSupportFragmentManager().popBackStack();
}
}
在我看来,最好的解决方案是:
JAVA解决方案
创建简单的界面:
public interface IOnBackPressed {
/**
* If you return true the back press will not be taken into account, otherwise the activity will act naturally
* @return true if your processing has priority if not false
*/
boolean onBackPressed();
}
在你的活动中
public class MyActivity extends Activity {
@Override public void onBackPressed() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
if (!(fragment instanceof IOnBackPressed) || !((IOnBackPressed) fragment).onBackPressed()) {
super.onBackPressed();
}
} ...
}
最后在你的片段中:
public class MyFragment extends Fragment implements IOnBackPressed{
@Override
public boolean onBackPressed() {
if (myCondition) {
//action not popBackStack
return true;
} else {
return false;
}
}
}
科特林解决方案
- 创建界面
interface IOnBackPressed {
fun onBackPressed(): Boolean
}
2 - 准备你的活动
class MyActivity : AppCompatActivity() {
override fun onBackPressed() {
val fragment =
this.supportFragmentManager.findFragmentById(R.id.main_container)
(fragment as? IOnBackPressed)?.onBackPressed()?.not()?.let {
super.onBackPressed()
}
}
}
3 - 在您的目标片段中实施
class MyFragment : Fragment(), IOnBackPressed {
override fun onBackPressed(): Boolean {
return if (myCondition) {
//action not popBackStack
true
} else {
false
}
}
}
R.id.main_container
是什么?那是 FragmentPager 的 ID 吗?
.onBackPressed()?.takeIf { !it }?.let{...}
吗? .not()
只是返回逆。
val fragment = this.supportFragmentManager.findFragmentById(R.id.flContainer) as? NavHostFragment val currentFragment = fragment?.childFragmentManager?.fragments?.get(0) as? IOnBackPressed currentFragment?.onBackPressed()?.takeIf { !it }?.let{ super.onBackPressed() }
这适用于使用 Kotlin 和 NavigationController 的人
override fun onBackPressed() { val fragment = this.supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment val currentFragment = fragment?.childFragmentManager?.fragments?.get(0) as? FragmentOnBackPressListener if (currentFragment != null) { currentFragment.onBackPressed().takeIf { !it }?.let { super.onBackPressed() } } else { super.onBackPressed() } }
如果您使用 androidx.appcompat:appcompat:1.1.0
或更高版本,则可以将 OnBackPressedCallback
添加到片段中,如下所示
requireActivity()
.onBackPressedDispatcher
.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Log.d(TAG, "Fragment back pressed invoked")
// Do custom work here
// if you want onBackPressed() to be called as normal afterwards
if (isEnabled) {
isEnabled = false
requireActivity().onBackPressed()
}
}
}
)
请参阅https://developer.android.com/guide/navigation/navigation-custom-back
androidx-core-ktx
,则可以使用 requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { /* code to be executed when back is pressed */ }
LifecycleOwner
参数。没有它,如果按下后退按钮,之后启动的任何片段都将调用 handleBackPressed()
。
根据@HaMMeRed 的回答,这里的伪代码应该如何工作。假设您的主要活动称为 BaseActivity
,它有子片段(如在 SlidingMenu lib 示例中)。以下是步骤:
首先,我们需要创建接口和实现其接口的类以具有泛型方法
创建类接口 OnBackPressedListener public interface OnBackPressedListener { public void doBack(); } 创建实现 OnBackPressedListener 技能的类 public class BaseBackPressedListener implements OnBackPressedListener { private final FragmentActivity activity;公共 BaseBackPressedListener(FragmentActivity 活动) { this.activity = 活动; } @Override public void doBack() { activity.getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);从现在开始,我们将处理我们的代码 BaseActivity 及其片段 在您的类 BaseActivity 之上创建私有侦听器 protected OnBackPressedListener onBackPressedListener;创建在 BaseActivity 中设置监听器的方法 public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) { this.onBackPressedListener = onBackPressedListener; } 在覆盖 onBackPressed 实现类似 @Override public void onBackPressed() { if (onBackPressedListener != null) onBackPressedListener.doBack();否则 super.onBackPressed();在 onCreateView 的片段中,您应该添加我们的监听器 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { activity = getActivity(); ((BaseActivity)activity).setOnBackPressedListener(new BaseBackPressedListener(activity));查看视图 = ... ; //带有视图的东西返回视图; }
瞧,现在当您在片段中单击返回时,您应该捕获自定义的返回方法。
onBackPressed()
中按下后退按钮时正在显示哪个片段?
((BaseActivity)activity).setOnBackPressedListener(new OnBackpressedListener(){ public void doBack() { //...your stuff here }});
这对我有用:https://stackoverflow.com/a/27145007/3934111
@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){
// handle back button's click listener
return true;
}
return false;
}
});
}
如果您想要这种功能,您需要在 Activity 中覆盖它,然后向所有片段添加一个 YourBackPressed
接口,只要按下后退按钮,您就会在相关片段上调用该接口。
编辑:我想附加我以前的答案。
如果我今天要这样做,我会使用广播,或者如果我希望其他面板同步更新到主/主要内容面板,我可能会使用有序广播。
支持库中的 LocalBroadcastManager
可以提供帮助,您只需在 onBackPressed
中发送广播并订阅您关心的片段。我认为 Messaging 是一个更加解耦的实现,并且可以更好地扩展,所以这将是我现在的官方实现建议。只需使用 Intent
的操作作为您的消息的过滤器。发送您新创建的 ACTION_BACK_PRESSED
,从您的活动中发送并在相关片段中收听。
LocalBroadcastManager
不能进行有序广播
这些都不容易实现,也不会以最佳方式运行。
片段有一个方法调用 onDetach 可以完成这项工作。
@Override
public void onDetach() {
super.onDetach();
PUT YOUR CODE HERE
}
这样就可以了。
isRemoving()
。
Google 在 Fragment
中发布了一个新的 API 来处理 onBackPressed
:
activity?.onBackPressedDispatcher?.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
}
})
只需在片段之间转换时添加 addToBackStack
,如下所示:
fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack("tag").commit();
如果你写 addToBackStack(null)
,它会自己处理它,但如果你给一个 tag ,你应该手动处理它。
新的更好的方法:在 Fragment
中的一段代码将帮助您捕获后按事件。
JAVA
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
Toast.makeText(mContext, "back pressed", Toast.LENGTH_SHORT).show();
// And when you want to go back based on your condition
if (yourCondition) {
this.setEnabled(false);
requireActivity().onBackPressed();
}
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
}
科特林
activity?.onBackPressedDispatcher?.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
}
})
使用 Navigation component 您可以做到 like this:
爪哇
public class MyFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This callback will only be called when MyFragment is at least Started.
OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
@Override
public void handleOnBackPressed() {
// Handle the back button event
}
});
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
// The callback can be enabled or disabled here or in handleOnBackPressed()
}
...
}
科特林
class MyFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// This callback will only be called when MyFragment is at least Started.
val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
// Handle the back button event
}
// The callback can be enabled or disabled here or in the lambda
}
...
}
由于这个问题和一些答案已经超过五年了,让我分享我的解决方案。这是@oyenigun 答案的后续和现代化
更新:在本文的底部,我添加了一个使用抽象片段扩展的替代实现,它根本不涉及活动,这对于任何具有更复杂片段层次结构的人都非常有用,其中涉及需要不同返回行为的嵌套片段。
我需要实现这一点,因为我使用的一些片段具有较小的视图,我想用后退按钮关闭它们,例如弹出的小信息视图等,但这对于需要覆盖的行为的任何人都有好处片段内的后退按钮。
首先,定义一个接口
public interface Backable {
boolean onBackPressed();
}
这个接口,我称之为 Backable
(我是命名约定的坚持者),只有一个方法 onBackPressed()
,它必须返回一个 boolean
值。我们需要强制一个布尔值,因为我们需要知道按下后退按钮是否“吸收”了后退事件。返回 true
表示它已经完成,不需要进一步的操作,否则,false
表示仍然必须执行默认的返回操作。这个接口应该是它自己的文件(最好在一个名为 interfaces
的单独包中)。请记住,将类分成包是一种很好的做法。
二、找到最上面的fragment
我创建了一个方法,该方法返回返回堆栈中的最后一个 Fragment
对象。我使用标签...如果您使用 ID,请进行必要的更改。我在处理导航状态等的实用程序类中有这个静态方法......但当然,把它放在最适合你的地方。为了启发,我把我的放在一个名为 NavUtils
的类中。
public static Fragment getCurrentFragment(Activity activity) {
FragmentManager fragmentManager = activity.getFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
String lastFragmentName = fragmentManager.getBackStackEntryAt(
fragmentManager.getBackStackEntryCount() - 1).getName();
return fragmentManager.findFragmentByTag(lastFragmentName);
}
return null;
}
确保返回堆栈计数大于 0,否则可能会在运行时抛出 ArrayOutOfBoundsException
。如果不大于 0,则返回 null。稍后我们将检查空值...
三、在一个片段中实现
在您需要覆盖后退按钮行为的任何片段中实现 Backable
接口。添加实现方法。
public class SomeFragment extends Fragment implements
FragmentManager.OnBackStackChangedListener, Backable {
...
@Override
public boolean onBackPressed() {
// Logic here...
if (backButtonShouldNotGoBack) {
whateverMethodYouNeed();
return true;
}
return false;
}
}
在 onBackPressed()
覆盖中,放置您需要的任何逻辑。如果您希望后退按钮不弹出后退堆栈(默认行为),请返回 true,表明您的后退事件已被吸收。否则,返回假。
最后,在您的活动中...
覆盖 onBackPressed()
方法并向其中添加此逻辑:
@Override
public void onBackPressed() {
// Get the current fragment using the method from the second step above...
Fragment currentFragment = NavUtils.getCurrentFragment(this);
// Determine whether or not this fragment implements Backable
// Do a null check just to be safe
if (currentFragment != null && currentFragment instanceof Backable) {
if (((Backable) currentFragment).onBackPressed()) {
// If the onBackPressed override in your fragment
// did absorb the back event (returned true), return
return;
} else {
// Otherwise, call the super method for the default behavior
super.onBackPressed();
}
}
// Any other logic needed...
// call super method to be sure the back button does its thing...
super.onBackPressed();
}
我们在后台堆栈中获取当前片段,然后我们进行空检查并确定它是否实现了我们的 Backable
接口。如果是,请确定该事件是否已被吸收。如果是这样,我们完成了 onBackPressed()
并且可以返回。否则,将其视为正常的后按并调用 super 方法。
不参与活动的第二种选择
有时,您根本不希望 Activity 处理此问题,您需要直接在片段中处理它。但是谁说你不能有带有 back press API 的 Fragments 呢?只需将您的片段扩展到一个新类。
创建一个扩展 Fragment 并实现 View.OnKeyListner
接口的抽象类...
import android.app.Fragment;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
public abstract class BackableFragment extends Fragment implements View.OnKeyListener {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(this);
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackButtonPressed();
return true;
}
}
return false;
}
public abstract void onBackButtonPressed();
}
如您所见,任何扩展 BackableFragment
的片段都将使用 View.OnKeyListener
界面自动捕获返回点击。只需使用标准逻辑从已实现的 onKey()
方法中调用抽象 onBackButtonPressed()
方法来识别后退按钮按下。如果您需要注册除后退按钮以外的按键点击,只需确保在片段中覆盖 onKey()
时调用 super
方法,否则您将覆盖抽象中的行为。
使用简单,只需扩展和实现:
public class FragmentChannels extends BackableFragment {
...
@Override
public void onBackButtonPressed() {
if (doTheThingRequiringBackButtonOverride) {
// do the thing
} else {
getActivity().onBackPressed();
}
}
...
}
由于超类中的 onBackButtonPressed()
方法是抽象的,因此一旦扩展就必须实现 onBackButtonPressed()
。它返回 void
是因为它只需要在片段类中执行一个动作,而不需要将按下的吸收传递回 Activity。 确保如果您对后退按钮所做的任何操作都不需要处理,则您确实调用了 Activity onBackPressed()
方法,否则,后退按钮将被禁用...而您不需要想要那个!
注意事项 如您所见,这会将关键侦听器设置为片段的根视图,我们需要关注它。如果扩展此类的片段(或具有相同内容的其他内部片段或视图)中涉及编辑文本(或任何其他窃取焦点的视图),则需要单独处理。有一篇关于 extending an EditText 的好文章可以让您将注意力转移到背压上。
我希望有人觉得这很有用。快乐编码。
super.onBackPressed();
两次?
currentFragment
的空状态,每个场景只调用一次。如果片段不为 null 并且片段实现了 Backable
接口,则不采取任何操作。如果片段不为 null 并且没有实现 Backable
,我们调用 super 方法。如果片段为空,它会跳到最后一个超级调用。
currentFragment
不为 null 并且是 Backable 的实例并且它被分离(我们按下 back
按钮并关闭片段),则调用第一次出现的 super.onBackPressed();
,然后调用第二次。
instanceof
隐式执行 null 检查,因此无需在此之前显式检查 null
解决方案很简单:
如果您有一个所有片段都扩展的基片段类,则将此代码添加到它的类中,否则创建这样一个基片段类
/*
* called when on back pressed to the current fragment that is returned
*/
public void onBackPressed()
{
// add code in super class when override
}
在您的 Activity 类中,按如下方式覆盖 onBackPressed:
private BaseFragment _currentFragment;
@Override
public void onBackPressed()
{
super.onBackPressed();
_currentFragment.onBackPressed();
}
在您的 Fragment 类中,添加您想要的代码:
@Override
public void onBackPressed()
{
setUpTitle();
}
onBackPressed()
导致 Fragment 与 Activity 分离。
根据@Sterling Diaz 的回答,我认为他是对的。但是有些情况会出错。 (例如旋转屏幕)
所以,我认为我们可以检测isRemoving()
是否实现了目标。
您可以将其写入 onDetach()
或 onDestroyView()
。这是工作。
@Override
public void onDetach() {
super.onDetach();
if(isRemoving()){
// onBackPressed()
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if(isRemoving()){
// onBackPressed()
}
}
您应该为您的项目添加界面,如下所示;
public interface OnBackPressed {
void onBackPressed();
}
然后,你应该在你的片段上实现这个接口;
public class SampleFragment extends Fragment implements OnBackPressed {
@Override
public void onBackPressed() {
//on Back Pressed
}
}
您可以在您的活动 onBackPressed 事件下触发此 onBackPressed 事件,如下所示;
public class MainActivity extends AppCompatActivity {
@Override
public void onBackPressed() {
Fragment currentFragment = getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1);
if (currentFragment instanceof OnBackPressed) {
((OnBackPressed) currentFragment).onBackPressed();
}
super.onBackPressed();
}
}
getActivity().onBackPressed();
,因为它会调用异常:“java.lang.StackOverflowError: stack size 8MB”。
在片段的 onCreate 方法中添加以下内容:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
//Handle the back pressed
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
}
callback.remove()
删除回调。
如果您使用 EventBus,它可能是一个更简单的解决方案:
在你的片段中:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
EventBus.getDefault().register(this);
}
@Override
public void onDetach() {
super.onDetach();
EventBus.getDefault().unregister(this);
}
// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
getSupportFragmentManager().popBackStack();
}
在您的 Activity 类中,您可以定义:
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
super.onBackPressed();
}
@Override
public void onBackPressed() {
EventBus.getDefault().post(new BackPressedMessage(true));
}
BackPressedMessage.java 只是一个 POJO 对象
这是超级干净的,没有接口/实现的麻烦。
好吧,我这样做了,它对我有用
简单的界面
FragmentOnBackClickInterface.java
public interface FragmentOnBackClickInterface {
void onClick();
}
示例实现
MyFragment.java
public class MyFragment extends Fragment implements FragmentOnBackClickInterface {
// other stuff
public void onClick() {
// what you want to call onBackPressed?
}
然后只需覆盖活动中的 onBackPressed
@Override
public void onBackPressed() {
int count = getSupportFragmentManager().getBackStackEntryCount();
List<Fragment> frags = getSupportFragmentManager().getFragments();
Fragment lastFrag = getLastNotNull(frags);
//nothing else in back stack || nothing in back stack is instance of our interface
if (count == 0 || !(lastFrag instanceof FragmentOnBackClickInterface)) {
super.onBackPressed();
} else {
((FragmentOnBackClickInterface) lastFrag).onClick();
}
}
private Fragment getLastNotNull(List<Fragment> list){
for (int i= list.size()-1;i>=0;i--){
Fragment frag = list.get(i);
if (frag != null){
return frag;
}
}
return null;
}
这是我的解决方案:
在 MyActivity.java 中:
public interface OnBackClickListener {
boolean onBackClick();
}
private OnBackClickListener onBackClickListener;
public void setOnBackClickListener(OnBackClickListener onBackClickListener) {
this.onBackClickListener = onBackClickListener;
}
@Override
public void onBackPressed() {
if (onBackClickListener != null && onBackClickListener.onBackClick()) {
return;
}
super.onBackPressed();
}
在片段中:
((MyActivity) getActivity()).setOnBackClickListener(new MyActivity.OnBackClickListener() {
@Override
public boolean onBackClick() {
if (condition) {
return false;
}
// some codes
return true;
}
});
在 kotlin 中,它更简单。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
//
}
})
}
public class MyActivity extends Activity {
protected OnBackPressedListener onBackPressedListener;
public interface OnBackPressedListener {
void doBack();
}
public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
this.onBackPressedListener = onBackPressedListener;
}
@Override
public void onBackPressed() {
if (onBackPressedListener != null)
onBackPressedListener.doBack();
else
super.onBackPressed();
}
@Override
protected void onDestroy() {
onBackPressedListener = null;
super.onDestroy();
}
}
在您的片段中添加以下内容,不要忘记实现 mainactivity 的接口。
public class MyFragment extends Framgent implements MyActivity.OnBackPressedListener {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((MyActivity) getActivity()).setOnBackPressedListener(this);
}
@Override
public void doBack() {
//BackPressed in activity will call this;
}
}
这只是一个可以解决问题的小代码:
getActivity().onBackPressed();
希望它可以帮助某人:)
您可以像这样使用 onBackPressedDispatcher
的父活动:
val backpress = requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, true) {
// here dispatcher works for any action when back pressed
}
您还可以随时从片段启用/禁用后按按钮,如下所示:
backpress.isEnabled = true/false
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
//your code
}
@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
replaceFragmentToBackStack(getActivity(), WelcomeFragment.newInstance(bundle), tags);
return true;
}
return false;
}
});
}
使用 onDestroyView() 怎么样?
@Override
public void onDestroyView() {
super.onDestroyView();
}
i = i
或 if (1 < 0) {}
相同。
只需按照以下步骤操作:
总是在添加片段时,
fragmentTransaction.add(R.id.fragment_container, detail_fragment, "Fragment_tag").addToBackStack(null).commit();
然后在主活动中,覆盖 onBackPressed()
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
} else {
finish();
}
要处理应用程序中的后退按钮,
Fragment f = getActivity().getSupportFragmentManager().findFragmentByTag("Fragment_tag");
if (f instanceof FragmentName) {
if (f != null)
getActivity().getSupportFragmentManager().beginTransaction().remove(f).commit()
}
而已!
非常简短而甜蜜的答案:
getActivity().onBackPressed();
我的案例的整个场景的解释:
我在 MainActivity 中有 FragmentA,我正在从 FragmentA 打开 FragmentB(FragmentB 是 FragmentA 的子片段或嵌套片段)
Fragment duedateFrag = new FragmentB();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container_body, duedateFrag);
ft.addToBackStack(null);
ft.commit();
现在,如果您想从 FragmentB 转到 FragmentA,您只需将 getActivity().onBackPressed();
放入 FragmentB。
根据 AndroidX release notes,发布 androidx.activity 1.0.0-alpha01
并引入 ComponentActivity
,这是现有 FragmentActivity
和 AppCompatActivity
的新基类。而这个版本为我们带来了一个新功能:
您现在可以通过 addOnBackPressedCallback
注册 OnBackPressedCallback
以接收 onBackPressed()
回调,而无需在您的 Activity 中覆盖该方法。
通过处理 onBackPressed 提供自定义后退导航现在更容易使用片段内的回调。
class MyFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (true == conditionForCustomAction) {
myCustomActionHere()
} else NavHostFragment.findNavController(this@MyFragment).navigateUp();
}
}
requireActivity().onBackPressedDispatcher.addCallback(
this, onBackPressedCallback
)
...
}
如果您想要基于某些条件的默认后退操作,您可以使用:
NavHostFragment.findNavController(this@MyFragment).navigateUp();