Xamarin.Forms.SwipeGesture 和 ScrollView 在 Android 上不能一起工作 [英] Xamarin.Forms. SwipeGesture and ScrollView don't work together on Android

查看:14
本文介绍了Xamarin.Forms.SwipeGesture 和 ScrollView 在 Android 上不能一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将 Grid 与 SwipeGesture 和 ScrollView 一起使用.ScrollView 运行良好,但 SwipeGesture 不仅适用于 Android.在 iOS 中我没有问题.

I use Grid with SwipeGesture and ScrollView. ScrollView works well but SwipeGesture doesn't work only Android. In iOS I have not problem.

为什么?请帮帮我

<Grid x:Name="grid">
     <Grid.RowDefinitions>
          <RowDefinition Height="*"/>
           <RowDefinition Height="auto"/>
      </Grid.RowDefinitions>

      <ScrollView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        ...
     </ScrollView>
 </Grid>

C#:

 var leftSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Right };
 leftSwipeGesture.Threshold = 50;
 leftSwipeGesture.Swiped += (sender, e) => Navigation.PopAsync();
 grid.GestureRecognizers.Add(leftSwipeGesture);

推荐答案

我根据 link 解决了这个问题.我创建了一个新组件:

I resolved this problem based on link. I created a new component:

public class GestureScrollView : ScrollView
{
    public event EventHandler SwipeLeft;
    public event EventHandler SwipeRight;

    public void OnSwipeLeft() =>
        SwipeLeft?.Invoke(this, null);

    public void OnSwipeRight() =>
        SwipeRight?.Invoke(this, null);
}

Android 渲染器:

Android renderer:

[assembly: ExportRenderer(typeof(GestureScrollView), typeof(GestureScrollViewRenderer))]
namespace SwipeScrollView.Droid.Platform.Renderers
{
public class GestureScrollViewRenderer : ScrollViewRenderer
{
    readonly CustomGestureListener _listener;
    readonly GestureDetector _detector;

    public GestureScrollViewRenderer(Context context) : base(context)
    {
        _listener = new CustomGestureListener();
        _detector = new GestureDetector(context, _listener);
    }

    public override bool DispatchTouchEvent(MotionEvent e)
    {
        if (_detector != null)
        {
            _detector.OnTouchEvent(e);
            base.DispatchTouchEvent(e);
            return true;
        }

        return base.DispatchTouchEvent(e);
    }

    public override bool OnTouchEvent(MotionEvent ev)
    {
        base.OnTouchEvent(ev);

        if (_detector != null)
            return _detector.OnTouchEvent(ev);

        return false;
    }

    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        if (e.NewElement == null)
        {
            _listener.OnSwipeLeft -= HandleOnSwipeLeft;
            _listener.OnSwipeRight -= HandleOnSwipeRight;
        }

        if (e.OldElement == null)
        {
            _listener.OnSwipeLeft += HandleOnSwipeLeft;
            _listener.OnSwipeRight += HandleOnSwipeRight;
        }
    }

    void HandleOnSwipeLeft(object sender, EventArgs e) =>
        ((GestureScrollView)Element).OnSwipeLeft();

    void HandleOnSwipeRight(object sender, EventArgs e) =>
        ((GestureScrollView)Element).OnSwipeRight();
}
}

自定义手势监听器:

public class CustomGestureListener : GestureDetector.SimpleOnGestureListener
{
    static readonly int SWIPE_THRESHOLD = 100;
    static readonly int SWIPE_VELOCITY_THRESHOLD = 100;

    MotionEvent mLastOnDownEvent;

    public event EventHandler OnSwipeLeft;
    public event EventHandler OnSwipeRight;

    public override bool OnDown(MotionEvent e)
    {
        mLastOnDownEvent = e;

        return true;
    }

    public override bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
    {
        if (e1 == null)
            e1 = mLastOnDownEvent;

        float diffY = e2.GetY() - e1.GetY();
        float diffX = e2.GetX() - e1.GetX();

        if (Math.Abs(diffX) > Math.Abs(diffY))
        {
            if (Math.Abs(diffX) > SWIPE_THRESHOLD && Math.Abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
            {
                if (diffX > 0)
                    OnSwipeRight?.Invoke(this, null);
                else
                    OnSwipeLeft?.Invoke(this, null);
            }
        }

        return base.OnFling(e1, e2, velocityX, velocityY);
    }
}

核心:

<ctrl:GestureScrollView x:Name="gi"> ... </ctrl:GestureScrollView>

gi.SwipeLeft += (s, e) =>
    DisplayAlert("Gesture Info", "Swipe Left Detected", "OK");                     

gi.SwipeRight += (s, e) =>
    DisplayAlert("Gesture Info", "Swipe Right Detected", "OK");

这篇关于Xamarin.Forms.SwipeGesture 和 ScrollView 在 Android 上不能一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆