调用新Fragment页面时Activity已销毁 - Xamarin.Android
我之前在做类似的Xamarin.Android项目时也踩过这个坑,结合BottomNavigationView的特性,给你梳理下完整的解决方案:
一、先搞懂"Activity已销毁"错误的根源
这个报错本质是你在执行Fragment切换操作时,当前关联的Activity已经处于销毁(或正在销毁)的状态,常见场景有两种:
- 你在异步回调(比如网络请求结束后)里触发跳转,但此时用户可能已经退出了当前页面
- 直接用Fragment的Context去拿SupportFragmentManager,没先确认Activity是否还活着
二、正确实现跳转(同时保留底部菜单)
要保留底部菜单,核心就是不能启动新Activity,而是在当前BottomNavigationView所在Activity的Fragment容器里替换页面,步骤如下:
1. 先检查Activity状态再执行跳转
在你的个人资料Fragment的按钮点击事件里,先做存活校验,再拿Activity的SupportFragmentManager:
// 个人资料Fragment中按钮的点击事件处理 private void ProfileSettingsBtn_Click(object sender, EventArgs e) { // 先确认Activity是否存活,避免触发销毁状态下的操作 if (Activity == null || Activity.IsFinishing || Activity.IsDestroyed) { return; } // 获取当前Activity的Fragment管理器 var fragManager = Activity.SupportFragmentManager; var transaction = fragManager.BeginTransaction(); // 替换容器里的Fragment为目标页面(比如设置页SettingsFragment) transaction.Replace(Resource.Id.fragment_container, new SettingsFragment()); // 可选:加入回退栈,让用户按返回键能回到个人资料页 transaction.AddToBackStack(null); transaction.Commit(); }
2. 确认布局里的Fragment容器ID正确
你的主Activity布局(比如activity_main.axml)里,一定要有一个统一的Fragment容器,所有BottomNavigation的页面和跳转后的页面都在这里显示,确保ID和代码里的一致:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 这个就是所有Fragment的容器,ID要和代码里的对应上 --> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <!-- 底部导航栏 --> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_nav" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/windowBackground" app:menu="@menu/bottom_nav_menu" /> </LinearLayout>
3. 优化回退体验(可选)
当用户从跳转后的页面返回时,底部导航应该自动选中之前的个人资料项,可以在主Activity里重写OnBackPressed:
public override void OnBackPressed() { var fragManager = SupportFragmentManager; if (fragManager.BackStackEntryCount > 0) { // 弹出回退栈,回到上一个Fragment fragManager.PopBackStack(); // 同步底部导航的选中状态为个人资料项 bottomNav.SelectedItemId = Resource.Id.nav_profile; } else { base.OnBackPressed(); } }
三、避坑小提示
- 别在Fragment的
OnDestroy、OnDestroyView生命周期之后执行Fragment切换 - 如果是异步操作后触发跳转,记得先检查Fragment的
IsActive属性:
// 比如网络请求完成后的回调 private void OnRequestFinished() { if (!IsActive) return; // 这里再执行跳转逻辑 }
内容的提问来源于stack exchange,提问作者broliverparker
相关产品推荐
相关产品推荐

