Слайдер форм Xamarin в ListView в TabbedPage не скользит правильно

У меня есть DataTemplate, который помещает ползунок в ListView внутри TabbedPage. В Android ползунок не перемещается правильно, и скольжение слева направо активирует функцию скольжения TabbedPage. Если ползунок находится за пределами ListView, он работает правильно. Как я могу предотвратить родительский контроль ползунка от обработки жеста перетаскивания?

Метод ViewParent.requestDisallowInterceptTouchEvent(boolean) может помочь, но какой рендер и т. Д. Я бы сделал?

Видео выпуска со слайдером

1 ответ

Решение

Создать SliderRenderer, а затем позвоните RequestDisallowInterceptTouchEvent(boolean) в DispatchTouchEvent(MotionEvent e), это может решить эту проблему, вот мой код:

MainPage:

        var tabsXaml = new TabbedPage { Title = "Working with ListView" };
        tabsXaml.Children.Add(new BasicListXaml { Title = "Basic", Icon = "icon.png" } );
        tabsXaml.Children.Add(new JustView { Title = "JustView", Icon = "icon.png" });
        tabsXaml.Children.Add(new UnevenRowsXaml { Title = "UnevenX", Icon = "icon.png" });
        tabsXaml.Children.Add(new SliderPage { Title = "SliderPage", Icon = "icon.png" });
        MainPage = tabsXaml;

Вторая страница в TabbedPage:

<ContentPage.Content>
    <local:MyListView x:Name="listView" ItemSelected="OnItemSelected">
        <local:MyListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout>
                        <local:MySlider HorizontalOptions="Fill"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </local:MyListView.ItemTemplate>
    </local:MyListView>
</ContentPage.Content>

SlidererRenderer:

   public override bool DispatchTouchEvent(MotionEvent e)
    {
        switch (e.Action)
        {
            case MotionEventActions.Down:
                Parent.Parent.Parent.Parent.Parent.Parent.Parent.RequestDisallowInterceptTouchEvent(true);                    
                break;
            case MotionEventActions.Move:
                 //This is the core of the problem!!!
                Parent.Parent.Parent.Parent.Parent.Parent.Parent.RequestDisallowInterceptTouchEvent(true);
                break;
            case MotionEventActions.Up:
                break;
            default:
                break;
        }
        return base.DispatchTouchEvent(e);
    }

Вы должны позвонить RequestDisallowInterceptTouchEvent(true) метод. Parent.Parent.Parent.Parent.Parent.Parent.Parent в моем коде означает Xamarin.Forms.Platform.Android.PageRendererПричина того, что Slider не могу работать прямо в видео, что page(в моем коде это JustView) не позволяют слайдеру обрабатывать жест перетаскивания.

введите описание изображения здесь

Я основываю свой ответ на решении, предложенном Йорком Шеном. Мне не нравилось жестко запрограммированное родительское вложение, поэтому я просто добавил функцию, которая помогает найти средство визуализации, для которого мы хотим вызватьRequestDisallowInterceptTouchEvent. Мой слайдер был вложен в другое представление, а это значит, что мне нужен родительский уровень другого уровня. Итак, вы идете:

public override bool DispatchTouchEvent(MotionEvent e)
{
    switch (e.Action)
    {
        case MotionEventActions.Down:
            (_navigationPage ??= GetNavigationPage(Parent)).RequestDisallowInterceptTouchEvent(true);
            break;
        case MotionEventActions.Move:
            //This is the core of the problem!!!
            _navigationPage.RequestDisallowInterceptTouchEvent(true);
            break;
        case MotionEventActions.Up:
            break;
        default:
            break;
    }
    return base.DispatchTouchEvent(e);
}

private IViewParent _navigationPage;

private IViewParent GetNavigationPage(IViewParent parent)
{
    if (parent is NavigationPageRenderer)
        return parent;
    return GetNavigationPage(parent.Parent);
}
Другие вопросы по тегам