Xamarin.Forms Classe helper DualScreenInfo
La classe DualScreenInfo
consente di determinare il riquadro in cui si trova la visualizzazione, le dimensioni del riquadro, l'orientamento del dispositivo, l'angolo della cerniera e altro ancora.
Configurare DualScreenInfo
Seguire queste istruzioni per creare un layout a doppio schermo nell'app:
- Seguire le istruzioni introduttive per aggiungere NuGet e configurare la classe Android
MainActivity
. - Aggiungere
using Xamarin.Forms.DualScreen;
al file di classe. - Usare la
DualScreenInfo.Current
classe nell'app.
Proprietà
SpanningBounds
: nel layout esteso a due schermi, questa proprietà restituisce due rettangoli che indicano i limiti di ogni area visibile. Se la finestra non è estesa, verrà restituito un array vuoto.HingeBounds
: indica la posizione della cerniera sullo schermo.IsLandscape
: indica se il dispositivo è in modalità orizzontale. Questa informazione è utile perché le API di orientamento native non segnalano correttamente l'orientamento quando un'applicazione è estesa.SpanMode
: indica se il layout è in modalità Tall, Wide o SinglePane.
Inoltre, l'evento PropertyChanged
viene generato quando qualsiasi proprietà cambia e l'evento viene generato quando cambia l'angolo HingeAngleChanged
della cerniera.
Angolo della cerniera di polling su Android e UWP
Il metodo seguente è disponibile quando si accede DualScreenInfo
da progetti di piattaforma Android e UWP:
GetHingeAngleAsync
: recupera l'angolo corrente della cerniera del dispositivo. Quando si usa il simulatore, è possibile impostare HingeAngle modificando il sensore di pressione.
Questo metodo può essere richiamato dai renderer personalizzati in Android e UWP. Il codice seguente mostra un esempio di renderer personalizzato Android:
public class HingeAngleLabelRenderer : Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer
{
System.Timers.Timer _hingeTimer;
public HingeAngleLabelRenderer(Context context) : base(context)
{
}
async void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (_hingeTimer == null)
return;
_hingeTimer.Stop();
var hingeAngle = await DualScreenInfo.Current.GetHingeAngleAsync();
Device.BeginInvokeOnMainThread(() =>
{
if (_hingeTimer != null)
Element.Text = hingeAngle.ToString();
});
if (_hingeTimer != null)
_hingeTimer.Start();
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (_hingeTimer == null)
{
_hingeTimer = new System.Timers.Timer(100);
_hingeTimer.Elapsed += OnTimerElapsed;
_hingeTimer.Start();
}
}
protected override void Dispose(bool disposing)
{
if (_hingeTimer != null)
{
_hingeTimer.Elapsed -= OnTimerElapsed;
_hingeTimer.Stop();
_hingeTimer = null;
}
base.Dispose(disposing);
}
}
Accedere a DualScreenInfo nella finestra dell'applicazione
Il codice seguente illustra come accedere a DualScreenInfo
per la finestra dell'applicazione:
DualScreenInfo currentWindow = DualScreenInfo.Current;
// Retrieve absolute position of the hinge on the screen
var hingeBounds = currentWindow.HingeBounds;
// check if app window is spanned across two screens
if(currentWindow.SpanMode == TwoPaneViewMode.SinglePane)
{
// window is only on one screen
}
else if(currentWindow.SpanMode == TwoPaneViewMode.Tall)
{
// window is spanned across two screens and oriented top-bottom
}
else if(currentWindow.SpanMode == TwoPaneViewMode.Wide)
{
// window is spanned across two screens and oriented side-by-side
}
// Detect if any of the properties on DualScreenInfo change.
// This is useful to detect if the app window gets spanned
// across two screens or put on only one
currentWindow.PropertyChanged += OnDualScreenInfoChanged;
Applicare DualScreenInfo ai layout
La classe DualScreenInfo
include un costruttore che può accettare un layout e fornire informazioni sul layout in relazione ai dispositivi con doppio schermo:
<Grid x:Name="grid" ColumnSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Column1Width}" />
<ColumnDefinition Width="{Binding Column2Width}" />
<ColumnDefinition Width="{Binding Column3Width}" />
</Grid.ColumnDefinitions>
<Label FontSize="Large"
VerticalOptions="Center"
HorizontalOptions="End"
Text="I should be on the left side of the hinge" />
<Label FontSize="Large"
VerticalOptions="Center"
HorizontalOptions="Start"
Grid.Column="2"
Text="I should be on the right side of the hinge" />
</Grid>
public partial class GridUsingDualScreenInfo : ContentPage
{
public DualScreenInfo DualScreenInfo { get; }
public double Column1Width { get; set; }
public double Column2Width { get; set; }
public double Column3Width { get; set; }
public GridUsingDualScreenInfo()
{
InitializeComponent();
DualScreenInfo = new DualScreenInfo(grid);
BindingContext = this;
}
protected override void OnAppearing()
{
base.OnAppearing();
DualScreenInfo.PropertyChanged += OnInfoPropertyChanged;
UpdateColumns();
}
protected override void OnDisappearing()
{
base.OnDisappearing();
DualScreenInfo.PropertyChanged -= OnInfoPropertyChanged;
}
void UpdateColumns()
{
// Check if grid is on two screens
if (DualScreenInfo.SpanningBounds.Length > 0)
{
// set the width of the first column to the width of the layout
// that's on the left screen
Column1Width = DualScreenInfo.SpanningBounds[0].Width;
// set the middle column to the width of the hinge
Column2Width = DualScreenInfo.HingeBounds.Width;
// set the width of the third column to the width of the layout
// that's on the right screen
Column3Width = DualScreenInfo.SpanningBounds[1].Width;
}
else
{
Column1Width = 100;
Column2Width = 0;
Column3Width = 100;
}
OnPropertyChanged(nameof(Column1Width));
OnPropertyChanged(nameof(Column2Width));
OnPropertyChanged(nameof(Column3Width));
}
void OnInfoPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
UpdateColumns();
}
}
Lo screenshot seguente mostra il layout risultante: