Xamarin Android BottomNavigationBar选中事件致程序中断求助
问题复现表现
- 仅渲染UI时程序运行正常
- 给BottomNavigationBar绑定
NavigationItemSelected事件后,程序直接进入中断模式 - 即使注释掉事件处理方法内所有Fragment加载逻辑,异常依然触发
问题相关代码
private void BottomNavigation_NavigationItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e) { //LoadFragment(e.Item.ItemId); } void LoadFragment(int id) { Android.Support.V4.App.Fragment fragment = null; switch (id) { case Resource.Id.menu_Meeting: fragment = MeetingFragment.NewInstance(); break; case Resource.Id.menu_Project: fragment = ProjectFragment.NewInstance(); break; case Resource.Id.menu_Account: fragment = AccountFragment.NewInstance(); break; } if (fragment == null) return; SupportFragmentManager.BeginTransaction() .Replace(Resource.Id.content_frame, fragment) .Commit(); }
根因定位
空事件方法也触发崩溃,和Fragment加载逻辑无关,90%以上概率是以下两个原因:
- Android Support依赖版本不一致:项目中引入的所有
Xamarin.Android.Support.*开头的NuGet包版本号不统一,Support库之间存在强依赖关系,小版本号不匹配就会导致事件绑定、控件渲染环节抛出类型不匹配、空引用异常。 - 控件获取时机错误:在调用
SetContentView()加载布局之前就执行FindViewById获取BottomNavigationView实例,拿到的对象为null,给null对象绑定的事件触发时直接抛出空引用异常。
修复方案
按优先级依次排查修复:
- 第一步:统一Support库版本
打开NuGet包管理器,检查所有Xamarin.Android.Support.前缀的依赖包(包括AppCompat、Design、V4、Fragment等),将所有包版本修改为完全一致的数值,之后清理解决方案、删除bin/obj目录、重新生成项目部署测试。 - 第二步:修正控件绑定时机
确保Activity中先执行SetContentView()加载对应布局,再执行FindViewById获取BottomNavigationView实例,获取后增加非空判断再绑定事件,参考正确写法:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // 必须先加载布局 SetContentView(Resource.Layout.Main); // 再获取控件实例 var bottomNavigation = FindViewById<BottomNavigationView>(Resource.Id.bottom_nav); if (bottomNavigation != null) { bottomNavigation.NavigationItemSelected += BottomNavigation_NavigationItemSelected; // 可选:设置默认选中项,触发首次Fragment加载 bottomNavigation.SelectedItemId = Resource.Id.menu_Meeting; } }
- 第三步:验证空事件不崩溃后,取消
LoadFragment(e.Item.ItemId)的注释即可正常实现Tab切换逻辑。
内容的提问来源于stack exchange,提问作者Ye LIN Tun Net
相关产品推荐
相关产品推荐

