Мне нужно просмотреть элементы в моем списке, прокручивая вверх или вниз в .NET MAUI. В моем списке есть видео, которые я показываю с помощью YoutubeApi и MediaElement. (Tiktok, Instagram Reels и т. д.) Чем я хочу здесь заниматься;
Какой бы элемент ни был виден в данный момент, MediaElement.Play()
этого элемента должен работать. Я все равно не смог найти подходящего события прокрутки. Есть ли у кого-нибудь идеи по этому поводу?
Я попробовал все прилагаемые способы сделать это, но безуспешно.
Я хочу, чтобы она исчезала, когда вы проводите пальцем вверх, как карту, а когда вы ее тянете вниз, соответствующая карта возвращается. Или как в приложениях для социальных сетей. Будет неограниченная прокрутка, но каждый раз будет просмотр элемента.
Что именно вы уже пробовали? Вероятно, вы можете добиться этого с помощью CollectionView, например. задав линейную компоновку и заполнив элементы доступным пространством. Затем используйте точки привязки для управления поведением прокрутки.
Большое спасибо за ваш комментарий. Как я это пропустил.....
Такого макета и поведения прокрутки можно легко добиться с помощью 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
Пробовали CollectionView?