You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:26:33