添加Footer的MvxListView销毁时抛出异常问题咨询
我之前也碰到过这个一模一样的问题!当给MvxListView加了FooterView后,在Fragment的OnDestroyView或者Activity的OnDestroy阶段总会触发NullReferenceException,异常栈明确指向MvxListView.set_ItemsSource方法。
问题原因
MvvmCross在清理视图绑定的时候,会自动尝试清空ListView的ItemsSource,但此时FooterView相关的内部视图组件可能已经被Android系统回收,导致MvxListView内部访问空对象,抛出异常。
解决方案
方法1:视图销毁前手动移除FooterView
这是最直接且稳妥的方案,在视图销毁生命周期方法中,先主动移除FooterView,再让绑定正常清理:
public override void OnDestroyView() { var listView = View?.FindViewById<MvxListView>(Resource.Id.voucher_list_view); if (listView != null && listView.FooterViewsCount > 0) { // 获取并移除第一个FooterView(如果有多个,可循环移除) var footerView = listView.GetFooterViews()[0]; listView.RemoveFooterView(footerView); } // 一定要在移除FooterView之后再调用base方法 base.OnDestroyView(); }
如果是Activity,就在OnDestroy方法里做同样的操作。
方法2:自定义MvxListView增加空引用保护
如果不想在每个页面都手动处理,可以自定义一个安全版的MvxListView,重写ItemsSource的setter方法,增加空值检查和异常捕获:
public class SafeMvxListView : MvxListView { public SafeMvxListView(Context context, IAttributeSet attrs) : base(context, attrs) { } public SafeMvxListView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle) { } public override IEnumerable ItemsSource { set { // 当上下文已失效或视图已销毁时,跳过设置 if (Context == null || IsDestroyed) return; try { base.ItemsSource = value; } catch (NullReferenceException) { // 捕获异常,避免应用崩溃 } } } }
之后把布局里的Mvx.MvxListView替换成你的自定义控件即可:
<YourNamespace.SafeMvxListView android:id="@+id/voucher_list_view" android:layout_width="match_parent" android:layout_height="match_parent" app:MvxItemTemplate="@layout/voucher_list_item" app:MvxBind="ItemsSource Vouchers" />
方法3:调整绑定清理时机
通过自定义BindingContext,确保在清理绑定之前先移除FooterView。不过这个方案相对复杂,一般前两种方法就足够解决问题了。
总结
优先推荐方法1,主动在视图销毁前移除FooterView,从根源上避免MvxListView在清理绑定时访问已回收的FooterView组件,是最稳定的解决方式。
内容的提问来源于stack exchange,提问作者Tommy Jakobsen
相关产品推荐
相关产品推荐

