Xamarin中C#重写Fragment的bool方法报错:无合适重写方法
解决Xamarin Fragment中无法重写OnTouchEvent的问题
嘿,这个问题我之前也踩过坑!咱们先搞清楚报错的根源:
你在Activity里能重写OnTouchEvent是因为Activity本身就自带这个方法,它负责处理窗口级的触摸事件;但你继承的SupportFragment(也就是AndroidX的Fragment类)根本就没有OnTouchEvent这个可重写的成员方法,所以编译器才会报错“No suitable method found to override”。
那Fragment里要处理触摸事件该怎么做?给你两种常用的解决方案:
方案一:给Fragment的根View设置触摸监听
这是最直接的方式,把触摸逻辑绑定到Fragment加载的布局根View上:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Util; using Android.Views; using Android.Widget; using SupportFragment = Android.Support.V4.App.Fragment; using Android.Support.Design.Widget; using Android.Support.V7.App; using Android.Support.V4.Widget; using Android.Support.V4.App; using Android.Views.Animations; namespace EFCAndroid { public class Fragment_menu : SupportFragment { private float initialX; private ViewFlipper viewflipper; public override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); } public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.Inflate(Resource.Layout.fragment_menu, container, false); viewflipper = view.FindViewById<ViewFlipper>(Resource.Id.viewFlipper); viewflipper.SetInAnimation(Activity, Resource.Animation.fade_in); viewflipper.SetOutAnimation(Activity, Resource.Animation.fade_out); viewflipper.SetFlipInterval(5000); viewflipper.StartFlipping(); // 给根View绑定触摸事件监听 view.Touch += OnRootViewTouch; return view; } private void OnRootViewTouch(object sender, View.TouchEventArgs e) { var motionEvent = e.Event; switch(motionEvent.Action) { case MotionEventActions.Down: initialX = motionEvent.GetX(); break; case MotionEventActions.Up: float finalX = motionEvent.GetX(); if (initialX > finalX) { if (viewflipper.DisplayedChild == 1) break; viewflipper.ShowNext(); } else { if (viewflipper.DisplayedChild == 0) break; viewflipper.ShowPrevious(); } break; } // 设置e.Handled = true 表示消费此触摸事件,false则传递给下层View e.Handled = false; } } }
方案二:重写Fragment的OnDispatchTouchEvent(进阶)
如果你需要拦截Fragment范围内的所有触摸事件,可以重写OnDispatchTouchEvent方法(这个是Fragment具备的方法),不过这种场景相对少一些:
public override bool OnDispatchTouchEvent(MotionEvent e) { // 在这里处理你的触摸逻辑,和之前的逻辑类似 switch(e.Action) { case MotionEventActions.Down: initialX = e.GetX(); break; case MotionEventActions.Up: float finalX = e.GetX(); if (initialX > finalX) { if (viewflipper?.DisplayedChild == 1) break; viewflipper?.ShowNext(); } else { if (viewflipper?.DisplayedChild == 0) break; viewflipper?.ShowPrevious(); } break; } // 返回true表示拦截事件,false则传递给子View或Activity return base.OnDispatchTouchEvent(e); }
注意:使用OnDispatchTouchEvent时要确保viewflipper已经初始化(比如在OnViewCreated之后),避免空引用。
总结一下:Fragment和Activity的事件模型不一样,不要直接把Activity的重写方法搬到Fragment里,通过View绑定监听或者Fragment自带的OnDispatchTouchEvent就能解决问题啦~
内容的提问来源于stack exchange,提问作者Jayson E Garcia
相关产品推荐
相关产品推荐

