.NET MAUI по вертикали SwipeView (слайд в тикток и т. д.)

Мне нужно просмотреть элементы в моем списке, прокручивая вверх или вниз в .NET MAUI. В моем списке есть видео, которые я показываю с помощью YoutubeApi и MediaElement. (Tiktok, Instagram Reels и т. д.) Чем я хочу здесь заниматься;

Какой бы элемент ни был виден в данный момент, MediaElement.Play() этого элемента должен работать. Я все равно не смог найти подходящего события прокрутки. Есть ли у кого-нибудь идеи по этому поводу?

Я попробовал все прилагаемые способы сделать это, но безуспешно.

Пробовали CollectionView?

Julian 30.04.2024 13:13

Я хочу, чтобы она исчезала, когда вы проводите пальцем вверх, как карту, а когда вы ее тянете вниз, соответствующая карта возвращается. Или как в приложениях для социальных сетей. Будет неограниченная прокрутка, но каждый раз будет просмотр элемента.

Bestekarx 30.04.2024 13:16

Что именно вы уже пробовали? Вероятно, вы можете добиться этого с помощью CollectionView, например. задав линейную компоновку и заполнив элементы доступным пространством. Затем используйте точки привязки для управления поведением прокрутки.

Julian 30.04.2024 13:42

Большое спасибо за ваш комментарий. Как я это пропустил.....

Bestekarx 30.04.2024 13:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
281
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Макет

Такого макета и поведения прокрутки можно легко добиться с помощью CollectionView с линейным макетом и точками привязки:

<?xml version = "1.0" encoding = "utf-8" ?>
<ContentPage
  x:Class = "FullPageSnapCollection.MainPage"
  xmlns = "http://schemas.microsoft.com/dotnet/2021/maui"
  xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
  xmlns:fullPageSnapCollection = "clr-namespace:FullPageSnapCollection"
  x:DataType = "fullPageSnapCollection:MainViewModel">

  <Grid>

    <CollectionView
      HeightRequest = "500"
      HorizontalOptions = "Fill"
      VerticalOptions = "Center"
      ItemsSource = "{Binding Items}">

      <CollectionView.ItemsLayout>
        <LinearItemsLayout
          Orientation = "Vertical"
          SnapPointsType = "MandatorySingle"
          SnapPointsAlignment = "Start" />
      </CollectionView.ItemsLayout>

      <CollectionView.ItemTemplate>
        <DataTemplate x:DataType = "fullPageSnapCollection:MyModel">
          <Grid
            HeightRequest = "500"
            BackgroundColor = "{Binding BackgroundColor}"
            HorizontalOptions = "Fill">
            <Label
              Text = "{Binding Name}"
              VerticalOptions = "Center"
              HorizontalOptions = "Center"
              FontSize = "Title" />
          </Grid>
        </DataTemplate>
      </CollectionView.ItemTemplate>

    </CollectionView>

  </Grid>

</ContentPage>

Вам потребуется указать HeightRequest для CollectionView, а также для макета в DataTemplate, чтобы элементы имели ту же высоту, что и CollectionView. Вместе с точками привязки это должно привести к тому, что вы ищете. Для этого я также подготовил небольшой образец репозитория.

Если вам нужно определить, какой элемент в данный момент виден в центре (представления), вы можете подписаться на событие Scrolled и получить CenterItemIndex из аргументов события, как описано здесь.

Автоматическое воспроизведение/остановка

Чтобы воспроизвести видео, размещенное в MediaElement, нам нужно пойти на небольшую хитрость. Поскольку MediaElement не предоставляет никакого привязываемого и устанавливаемого свойства IsPlaying, нам нужно добавить его самостоятельно, расширив класс следующим образом, используя BindableProperty:

public class ExtendedMediaElement : MediaElement
{
    public bool IsPlaying
    {
        get => (bool)GetValue(IsPlayingProperty);
        set => SetValue(IsPlayingProperty, value);
    }

    public static readonly BindableProperty IsPlayingProperty = BindableProperty.Create(nameof(IsPlaying), typeof(bool), typeof(ExtendedMediaElement), false, propertyChanged: OnIsPlayingPropertyChanged);

    private static void OnIsPlayingPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var mediaElement = (ExtendedMediaElement)bindable;

        if (newValue is true)
        {
            mediaElement.Play();
        }
        else
        {
            mediaElement.Stop();
        }
    }
}

Теперь это позволяет нам привязываться к любому свойству класса модели для управления функциональностью воспроизведения/остановки путем обновления свойства.

Далее нам нужно добавить в нашу модель наблюдаемое свойство, которое будет использоваться для обновления привязываемого свойства, например:

public partial class MyModel(string videoUri) : ObservableObject
{
    public string VideoUri { get; } = videoUri;

    [ObservableProperty]
    private bool _isPlaying;
}

Вместо использования MediaElement мы будем использовать наш ExtendedMediaElement и в DataTemplate добавим привязку к добавленному привязываемому свойству IsPlaying:

<DataTemplate x:DataType = "fullPageSnapCollection:MyModel">
  <Grid
    HeightRequest = "500"
    BackgroundColor = "{Binding BackgroundColor}"
    HorizontalOptions = "Fill">
    <fullPageSnapCollection:ExtendedMediaElement
      Aspect = "Fill"
      Source = "{Binding VideoUri}"
      ShouldAutoPlay = "False"
      ShouldLoopPlayback = "True"
      ShouldShowPlaybackControls = "False"
      IsPlaying = "{Binding IsPlaying}" />
  </Grid>
</DataTemplate>

И последнее, но не менее важное: теперь мы можем использовать обработчик событий для события Scrolled CollectionView, чтобы обновить свойство IsPlaying каждого из экземпляров нашей модели в коде страницы, что впоследствии вызовет воспроизведение/остановку. функциональность:

public partial class MainPage : ContentPage
{
    private readonly MainViewModel _vm;

    public MainPage()
    {
        InitializeComponent();
        BindingContext = _vm = new MainViewModel();
    }

    private void ItemsView_OnScrolled(object? sender, ItemsViewScrolledEventArgs e)
    {
        var itemIndex = e.CenterItemIndex;

        _vm.Items[itemIndex].IsPlaying = true;

        foreach (var myModel in _vm.Items)
        {
            if (myModel != _vm.Items[itemIndex])
            {
                myModel.IsPlaying = false;
            }
        }
    }
}

Мне нужно достичь MediaElement, который эквивалентен CenterItemIndex, с помощью события прокрутки и вызвать MediaElement.Play(). Есть ли у вас какие-нибудь идеи на этот счет? Спасибо, сэр. :) prnt.sc/CuyMm4U7Kb_2 prnt.sc/rPTWoDAB1Yz9

Bestekarx 30.04.2024 19:47

Другие вопросы по теме