我希望添加一个自定义的ImageButton自动隐藏后,在Dotnet毛伊岛MediaElement页面几秒钟的能力。我宁愿直接添加控制媒体元素控件,但会很高兴与任何一个结果。我试图找出一种方法来隐藏控件使用IsBusy和IsNotBusy与计时器,但我有零的运气到目前为止。这里是项目的相关代码。
示例:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="NerdNewsNavigator2.View.LivePage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:viewmodel="clr-namespace:NerdNewsNavigator2.ViewModel"
Title=""
x:DataType="viewmodel:LiveViewModel"
BackgroundColor="Black"
Loaded="ContentPage_Loaded"
Shell.NavBarIsVisible="False"
Unloaded="ContentPage_Unloaded">
<Shell.BackButtonBehavior>
<BackButtonBehavior IsEnabled="True" IsVisible="False" />
</Shell.BackButtonBehavior>
<Grid>
<toolkit:MediaElement
x:Name="mediaElement"
ShouldAutoPlay="True"
ShouldShowPlaybackControls="True" />
<ImageButton
x:Name="btnFullScreen"
Grid.Row="0"
Margin="10"
Clicked="BtnFullScreen_Clicked"
HeightRequest="40"
HorizontalOptions="End"
IsVisible="{OnPlatform Android=true,
iOS=false,
WinUI=true,
MacCatalyst=true}"
Source="iconfullscreen.png"
VerticalOptions="Start"
WidthRequest="40">
<ImageButton.Behaviors>
<toolkit:IconTintColorBehavior TintColor="White" />
</ImageButton.Behaviors>
</ImageButton>
</Grid>
</ContentPage>
政务司司长:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Maui.Controls.PlatformConfiguration;
using Application = Microsoft.Maui.Controls.Application;
using Platform = Microsoft.Maui.ApplicationModel.Platform;
#if ANDROID
using Views = AndroidX.Core.View;
#endif
#if WINDOWS
using Microsoft.UI;
using Microsoft.UI.Windowing;
using WinRT;
using Microsoft.Maui.Controls;
#endif
namespace NerdNewsNavigator2.View;
/// <summary>
/// A class that manages watching Live video from twit.tv podcasting network
/// </summary>
public partial class LivePage : ContentPage
{
private bool _fullScreen = false;
/// <summary>
/// Initializes a new instance of <see cref="LivePage"/> class.
/// </summary>
/// <param name="liveViewModel">This classes <see cref="ViewModel"/> from <see cref="LiveViewModel"/></param>
public LivePage(LiveViewModel liveViewModel)
{
InitializeComponent();
BindingContext = liveViewModel;
}
private void BtnFullScreen_Clicked(object sender, EventArgs e)
{
if (_fullScreen)
{
_fullScreen = false;
RestoreScreen();
}
else
{
SetFullScreen();
_fullScreen = true;
}
}
/// <summary>
/// Method overrides <see cref="OnDisappearing"/> to stop playback when leaving a page.
/// </summary>
protected override void OnDisappearing()
{
mediaElement.Stop();
mediaElement.ShouldKeepScreenOn = false;
}
#region Load/Unload Events
#nullable enable
/// <summary>
/// Manages unload event from <see cref="mediaElement"/> after it is unloaded.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void ContentPage_Unloaded(object? sender, EventArgs e)
{
if (sender is null)
{
return;
}
mediaElement.Handler?.DisconnectHandler();
}
/// <summary>
/// Method Loads Video after page has finished being rendered.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ContentPage_Loaded(object? sender, EventArgs e)
{
if (sender is null)
{
return;
}
_ = LoadVideo();
}
/// <summary>
/// Method returns 720P URL for <see cref="mediaElement"/> to Play.
/// </summary>
/// <param name="m3UString"></param>
/// <returns></returns>
public static string ParseM3UPLaylist(string m3UString)
{
var masterPlaylist = MasterPlaylist.LoadFromText(m3UString);
var list = masterPlaylist.Streams.ToList();
return list.ElementAt(list.FindIndex(x => x.Resolution.Height == 720)).Uri;
}
/// <summary>
/// Method returns the Live stream M3U Url from youtube ID.
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static async Task<string> GetM3U_Url(string url)
{
var content = string.Empty;
var client = new HttpClient();
var youtube = new YoutubeClient();
var result = await youtube.Videos.Streams.GetHttpLiveStreamUrlAsync(url);
var response = await client.GetAsync(result);
if (response.IsSuccessStatusCode)
{
content = await response.Content.ReadAsStringAsync();
}
return content;
}
/// <summary>
/// Method Starts <see cref="MediaElement"/> Playback.
/// </summary>
/// <returns></returns>
private async Task LoadVideo()
{
var m3u = await LivePage.GetM3U_Url("F2NreNEmMy4");
mediaElement.Source = LivePage.ParseM3UPLaylist(m3u);
mediaElement.Play();
}
#nullable disable
#endregion
#if WINDOWS
/// <summary>
/// Method is required for switching Full Screen Mode for Windows
/// </summary>
private static Microsoft.UI.Windowing.AppWindow GetAppWindow(MauiWinUIWindow window)
{
var handle = WinRT.Interop.WindowNative.GetWindowHandle(window);
var id = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(handle);
var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(id);
return appWindow;
}
#endif
#nullable enable
/// <summary>
/// Method toggles Full Screen Off
/// </summary>
public void RestoreScreen()
{
#if WINDOWS
var window = GetParentWindow().Handler.PlatformView as MauiWinUIWindow;
if (window is not null)
{
var appWindow = GetAppWindow(window);
switch (appWindow.Presenter)
{
case Microsoft.UI.Windowing.OverlappedPresenter overlappedPresenter:
if (overlappedPresenter.State == Microsoft.UI.Windowing.OverlappedPresenterState.Maximized)
{
overlappedPresenter.SetBorderAndTitleBar(true, true);
overlappedPresenter.Restore();
}
break;
}
}
#endif
#if ANDROID
var activity = Platform.CurrentActivity;
if (activity == null || activity.Window == null) return;
Views.WindowCompat.SetDecorFitsSystemWindows(activity.Window, false);
var windowInsetsControllerCompat = Views.WindowCompat.GetInsetsController(activity.Window, activity.Window.DecorView);
var types = Views.WindowInsetsCompat.Type.StatusBars() |
Views.WindowInsetsCompat.Type.NavigationBars();
windowInsetsControllerCompat.Show(types);
#endif
}
/// <summary>
/// Method toggles Full Screen On
/// </summary>
private void SetFullScreen()
{
#if ANDROID
var activity = Platform.CurrentActivity;
if (activity == null || activity.Window == null) return;
Views.WindowCompat.SetDecorFitsSystemWindows(activity.Window, false);
var windowInsetsControllerCompat = Views.WindowCompat.GetInsetsController(activity.Window, activity.Window.DecorView);
var types = Views.WindowInsetsCompat.Type.StatusBars() |
Views.WindowInsetsCompat.Type.NavigationBars();
windowInsetsControllerCompat.SystemBarsBehavior = Views.WindowInsetsControllerCompat.BehaviorShowBarsBySwipe;
windowInsetsControllerCompat.Hide(types);
#endif
#if WINDOWS
var window = GetParentWindow().Handler.PlatformView as MauiWinUIWindow;
if (window is not null)
{
var appWindow = GetAppWindow(window);
switch (appWindow.Presenter)
{
case Microsoft.UI.Windowing.OverlappedPresenter overlappedPresenter:
overlappedPresenter.SetBorderAndTitleBar(false, false);
overlappedPresenter.Maximize();
break;
}
}
#endif
}
#nullable disable
}
在app.xaml.cs中还有其他代码可以使其正常工作。
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Application = Microsoft.Maui.Controls.Application;
using Platform = Microsoft.Maui.ApplicationModel.Platform;
#if WINDOWS
using Microsoft.UI;
using Microsoft.UI.Windowing;
using WinRT;
using Microsoft.Maui.Controls;
#endif
namespace NerdNewsNavigator2;
/// <summary>
/// A class that acts as a manager for <see cref="Application"/>
/// </summary>
public partial class App : Application
{
/// <summary>
/// This applications Dependancy Injection for <see cref="PositionDataBase"/> class.
/// </summary>
public static PositionDataBase PositionData { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="App"/> class.
/// </summary>
/// <param name="positionDataBase"></param>
public App(PositionDataBase positionDataBase)
{
InitializeComponent();
MainPage = new AppShell();
// Database Dependancy Injection START
PositionData = positionDataBase;
// Database Dependancy Injection END
LogController.InitializeNavigation(
page => MainPage!.Navigation.PushModalAsync(page),
() => MainPage!.Navigation.PopModalAsync());
}
#nullable enable
/// <summary>
/// A method to override the default <see cref="Window"/> behavior.
/// </summary>
/// <param name="activationState"></param>
/// <returns></returns>
protected override Window CreateWindow(IActivationState? activationState)
{
var window = base.CreateWindow(activationState);
window.Created += (s, e) =>
{
//NOTE: Change this to fetch the value true/false according to your app logic.
SetFullScreen(s, e);
};
window.Resumed += (s, e) =>
{
SetFullScreen(s, e);
};
return window;
}
/// <summary>
/// Method to set Full Screen status.
/// </summary>
/// <param name="sender"></param>
/// <param name="eventArgs"></param>
private static void SetFullScreen(object? sender, EventArgs eventArgs)
{
if (sender != null)
{
#if WINDOWS
var currentWindow = sender.As<Window>();
var uiWindow = currentWindow.Handler.PlatformView.As<MauiWinUIWindow>();
var handle = WinRT.Interop.WindowNative.GetWindowHandle(uiWindow);
var id = Win32Interop.GetWindowIdFromWindow(handle);
var appWindow = AppWindow.GetFromWindowId(id);
switch (appWindow.Presenter)
{
case OverlappedPresenter overlappedPresenter:
uiWindow.ExtendsContentIntoTitleBar = false;
{
overlappedPresenter.SetBorderAndTitleBar(true, true);
overlappedPresenter.Restore();
}
break;
}
#endif
}
}
#nullable disable
}
这是一个重复的代码很多,我不喜欢,但它的工作,我会弄清楚这一点后.如果我删除了全屏代码在App.xaml.cs的网页,我有无法正确加载.
控制设置全屏打开和关闭的Android和Windows。我想让它要么自动隐藏或直接添加到Maui媒体元素控件直接在酒吧。
1条答案
按热度按时间oxcyiej71#
好吧,我想通了!它结束了,我需要使用指针移动命令时,使用指针手势识别器,而不是指针移动。这是很简单的,我想通了。示例LivePage.xaml:
LivePage.xaml.cs
LiveViewModel.cs
BaseViewModel.cs
App.xaml.cs:这是windows全屏工作所必需的!!!
我相信有一个更好更简单的方法来做到这一点,但这工作,我现在使用它,直到有人想出一个更好的方法。