Descrizione dei componenti principali di Xamarin che permettono di comporre interfacce grafiche usando Xamarin.Forms. Principali layout manager di Xamarin From StackLayout, AbsoluteLayout, RelativeLayout, Grid e ListView
2. Layout (1)
Xamarin. Forms dispone di diversi layout e le funzionalità nell'organizzazione del contenuto sullo schermo.
I layout più importanti sono:
StackLayout: usato per disporre le visualizzazioni in modo lineare, orizzontalmente o verticalmente.
AbsoluteLayout: consente di organizzare le visualizzazioni impostando le coordinate termini di valori assoluti o rapporti.
RelativeLayout: usato per disporre le visualizzazioni impostando vincoli rispetto al relativo elemento padre le dimensioni
e posizione.
Grid: usato per disporre le viste in una griglia. Le righe e colonne possono essere specificate in termini di valori assoluti o
rapporti.
4. Allineamento ed Espansione (1)
Allineamento: controlla l'allineamento come una vista viene posizionata all'interno del layout del padre
quando il layout del padre contiene spazio inutilizzato (vale a dire, il layout del padre è maggiore della
dimensione combinata di tutti gli elementi figlio).
Espansione: indica se la visualizzazione deve utilizzare lo spazio aggiuntivo, se disponibile (usato solo
all’interno di uno StackLayout).
Tutti componenti grafici di xamarin. Forms ha proprietà HorizontalOptions e VerticalOptions, di tipo
LayoutOptions che determina l’allineamento ed espansione.
5. Allineamento ed Espansione (2)
LayoutOptions può assumere i valori:
Il Start, Center, End, e Fill campi vengono usati per definire l'allineamento
StartAndExpand, CenterAndExpand, EndAndExpand, e FillAndExpand
per definire allineamento ed espansione
La proprietà VerticalOptions definisce allineamento e estensione
verticale di una View
La proprietà HorizontalOptions definisce allineamento e
estensione orizzontale di una View
6. Allineamento ed Espansione (3)
Start posiziona la View sul lato sinistro del layout padre e per l'allineamento verticale,
posiziona la View all'inizio del layout padre
Center centra orizzontalmente o verticalmente la View
End posiziona la View sul lato destro di layout padre e per l'allineamento verticale,
posiziona la View nella parte inferiore del layout padre
Fill assicura che il View riempa la larghezza del layout padre e per l'allineamento
verticale, che assicura la View riempa in altezza del layout padre.
7. Allineamento ed Espansione (4)
Per implementare espasione viene aggiunto ai questi
precedenti “andExpand”
Questo va a dire che se alla View figlio venisse aggiunto
del contenuto questo continuerebbe ad aumentare il suo
spazio se disponibile
10. StackLayout (1)
Lo StackLayout viene utilizzato per mostrare View
lungo una riga orizzontale o verticale
StackLayout viene spesso utilizzato come il layout di base,
la disposizione di altri layout sullo schermo
11. StackLayout (2)
Per un esempio di quando StackLayout potrebbe essere una
buona scelta, prendere in considerazione un'app che è
necessario visualizzare un pulsante e un'etichetta con l'etichetta
allineata a sinistra e il pulsante allineato a destra.
<StackLayout Orientation="Horizontal">
<Label HorizontalOptions="StartAndExpand" Text="Label" />
<Button HorizontalOptions="End" Text="Button" />
</StackLayout>
12. AbsoluteLayout (1)
Viene utilizzato per mostrare View, con dimensioni e
posizioni date mediante valori assoluti o relativi alle
dimensioni del layout
A differenza di StackLayout e Grid, AbsoluteLayout
consente che View al suo interno si sovrappongano.
13. AbsoluteLayout (2)
La specifica i valori delle dimensioni della view figlio avviene tramite:
X posizione x (orizzontale) del punto di ancoraggio della view figlio
Y la posizione y (verticale) del punto di ancoraggio della view figlio
width la larghezza della view figlio
height l'altezza della view figlio
Questi quattro valori possono essere impostati come una proporzione o con un valore relativo
Questi vengono impostati tramite la property LayoutBounds di tipo Rectangle, che si inizializza con la sequenza x, y,
width, height.
14. AbsoluteLayout (3)
AbsoluteLayoutFlags specifica la modalità di interpretazione dei valori, e può essere
None tutti i valori sono assoluti espressi in px (valore di default)
All tutti i valori sono proporzionali
WidthProportional solo la larghezza è proporzionale
HeightProportional solo l’altezza è proporzionale
Xproportional solo la pozione X è proporzionale
Yproportional solo la pozione Y è proporzionale
PositionProportional le coordinate X e Y sono in proporzione
SizeProportional sia larghezza che altezza sono date in proporzione
15. AbsoluteLayout (4)
Valori proporzionali definiscono un valore di una proporzione
di una view figlio rispetto al padre, con valori espressi come un
double compreso tra 0 e 1
<Label Text="I'm bottom center on every device."
AbsoluteLayout.LayoutBounds=".5,1,.5,.1"
AbsoluteLayout.LayoutFlags="All" />
18. RelativeLayout (1)
RelativeLayout viene utilizzato per predisporre view,
con dimensione e posizione specificadoli rispetto ai
valori del layout che le contiene o rispetto ad altre
view in esso contenute
Il posizionamento di view all’interno di un RelativeLayout
avviene per mezzo di una ConstraintExpression
19. Il relative layout ha delle property dedicate a cui associare
ConstraintExpression che sono
Xconstraint
Yconstraint
WidthConstraint
HieghtContraint
20. RelativeLayout (2)
ConstraintExpression contiene le seguenti property
Type indica se il vincolo è riferito all’elemento padre o a un’altra view es.
Type=RelativeToParent
Property indica il nome della property su cui il ConstraintExpression si basa es.
Type=Width
Factor il fattore da applicare al valore della property es. Factor=0.5
Constant è un offset da applicare al valore es. Constant=100
ElementName è il nome della view con la quale viene impostata la relazione
23. Grid (1)
Questo layout permette la suddivisione in righe e colonne
Righe e colonne possono avere dimensioni assolute o
relative
Può essere usato per disporre le viste in una griglia, per
esempio:
Disposizione di pulsanti in un'app calcolatrice
24. Grid (2)
A differenza delle tabelle tradizionali, Grid non deduce il numero e dimensioni delle
righe e colonne dal contenuto
Grid al suo interno possiede le collections RowDefinitions e
ColumnDefinitions che contengono le informazioni su quante righe e colonne
verranno mostrate.
Le property RowDefinitions e ColumnDefinitions contengono rispettivamente
oggetti di tipo RowDefinition che dispone di una singola proprietà height e
ColumnDefinition un singola proprietà width. Width ed Height sono di tipo
GridUnitType
25. Grid (3)
GridUnitType può assumere valore
Auto dimensione automatica in base al contenuto della riga o colonna.
Specificato con GridUnitType.Auto in C# o come Auto in XAML
Proportional dimensioni di righe e colonne sono impostate con una
proporzione utilizzando lo spazio rimanente. In C# tramite GridUnitType.Star
e in XAML come #* (dove # è un numero). Se viene impostato solamente *
verrà riempito lo spazio rimanente
Assoluto un valore in pixel
26. Grid Definition Es.(1)
Esempio, si consideri un'applicazione che richieda tre
righe e due colonne con le seguenti caratteristiche.
La riga inferiore deve essere esattamente 200px
La riga superiore deve essere due volte la stessa altezza alla
riga centrale.
Nella colonna sinistra deve adattarsi al contenuto
La colonna a destra deve riempire lo spazio rimanente.
28. Elementi Grid
Per aggiungere view alla Grid è necessario aggiungerli
come elementi figlio usando Grid.Row e Grid.Column per
specificare il posizionamento
31. ListView
La ListView è un view usata per presentare una lista di
dati usando layout custom
L’oggetto ListView viene popolato con dati tramite la
property ItemsSource utilizzando una collection che
implementi Ienurable
L’aspetto di ogni elemento dell’elenco può essere
impostato tramite la property ItemTemplate di tipo
DataTemplate
33. ListView XAML e Code Behid (2)
using System.ComponentModel;
using Xamarin.Forms;
namespace AppOrientation
{
[DesignTimeVisible(true)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
teams.ItemsSource = new string[]{
"Juventus",
"Milan",
"Inter",
"Napoli",
"Roma"
};
}
}
}
34.
35. Display Post (1)
Requisiti
Package Manager Console → Install-Package Newtonsoft.Json
Android Mainifest → Required permission Internet
36. Display Post (2) Post Model
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace DisplayPostListView.Model
{
public class Post
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("userId")]
public int UserId { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("body")]
public string Body { get; set; }
public string ImageUrl { get; set; }
}
}
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati ….t,
"body": "quia et suscipitnsuscipit recusandae consequunt……."
},
//other posts
]
MODEL JSON
37. Display Post (3) BaseViewModel
public class BaseViewModel : INotifyPropertyChanged
{
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
38. Display Post (4) ItemListViewModel
public class ItemListViewModel : BaseViewModel
{
public ObservableCollection<Post> Posts { get; set; }
public ItemListViewModel()
{
this.Posts = new ObservableCollection<Post>();
}
public async Task UpdatePostsAsync()
{
var newPosts = await JsonPlaceholderHelper.GetPostsAsync();
this.Posts.Clear();
newPosts.ForEach((post) =>
{
post.ImageUrl = "https://picsum.photos/70/?image=" + newPosts.IndexOf(post);
this.Posts.Add(post);
});
}
}
39. Display Post (5)
JsonPlaceholderHelper
public static class JsonPlaceholderHelper
{
const string BASE_URL = "https://jsonplaceholder.typicode.com/";
const string POST_ENDPOINT = "posts";
public static async Task<List<Post>> GetPostsAsync()
{
using (var httpClient = new HttpClient())
{
var jsonString = await httpClient.GetStringAsync(BASE_URL + POST_ENDPOINT);
var posts = JsonConvert.DeserializeObject<List<Post>>(jsonString);
return posts;
}
}
}
41. Display Post (7) Code Behind
public partial class MainPage : ContentPage
{
ItemListViewModel itemListViewModel;
public MainPage()
{
InitializeComponent();
itemListViewModel = new ItemListViewModel();
BindingContext = itemListViewModel;
}
protected override async void OnAppearing()
{
base.OnAppearing();
await itemListViewModel.UpdatePostsAsync();
}
}
42. Display Post (8) BindingContext
Il BindingContext dice quale struttura ViewModel viene
usata come binding con oggetti che compongono
l’interfaccia XAML
44. Navigazione (1)
Xamarin.Forms offre diverse tipologie di navigazione
Navigazione gerarchica questa sfrutta la classe “NavigatonPage” che permette l’utente si scorrere le pagine avanti e indietro in base alle sue esigenze (Navigazione LIFO)
Tabbed Page è costituita da un elenco di schede (Tab) che impostano un’area di dettaglio
Carousel Page è costituita da un elenco di pagine che si possono scorrere trascinando un dito sullo schermo
Master Detail Page gestisce la navigazione tramite un menù verticale a comparsa che imposta la pagina da visualizzare come contenuto principale
Pagine Modali una pagina modale richiede agli utenti il completamento di un'attività indipendente, dalla quale non è possibile spostarsi fino a quando non viene completata o
annullata
Pop Up xamarin.forms permette due tipi di popup
Alert che avvisano l’utente
Action sheet che gestiscono una domanda e risposta rivolta all’utent
46. Navigazione gerarchica (1)
La classe NavigationPage offre un'esperienza di
navigazione gerarchica in cui l'utente è in grado di
scorrere le pagine avanti e indietro in base alle
esigenze. La classe implementa la navigazione come
stack LIFO (Last-In, First-Out) di oggetti Pagina. Questo
articolo illustra come usare la classe NavigationPage per
eseguire la navigazione in uno stack di pagine.
47. Navigazione gerarchica (2)
Per passare da una pagina all'altra, un'applicazione
esegue il push di una nuova pagina nello stack di
navigazione, in cui diventa la pagina attiva, come illustrato
nel diagramma seguente
48. Navigazione gerarchica (3)
Per passare da una pagina all'altra, un'applicazione
esegue il push di una nuova pagina nello stack di
navigazione, in cui diventa la pagina attiva, come illustrato
nel diagramma seguente
49. Es. Navigazione gerarchica (1)
In App.xaml.cs la main page deve essere di tipo
NavigationPage
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
}
50. Es. Navigazione Gerarchica (2)
Dalla main page aggiungo un pulsante che porta all next
page
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:AppNav2"
x:Class="AppNav2.MainPage">
<Button x:Name="btn" Text="Next Page" Clicked="btn_Clicked"></Button>
</ContentPage>
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private async void btn_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new NextPage());
}
}
XAML
CODE BEHIND
51. Es. Navigazione Gerarchica (3)
Dalla next page aggiunto un pulsante che porta alla main
page
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppNav2.NextPage">
<Button x:Name="Back" Clicked="Back_Clicked" Text="Back"></Button>
</ContentPage>
public partial class NextPage : ContentPage
{
public NextPage()
{
InitializeComponent();
}
private async void Back_Clicked(object sender, EventArgs e)
{
await Navigation.PopAsync();
}
}
XAML
CODE
BEHIND
53. Master Detail Page (1)
Gestisce la navigazione tramite un menù verticale ache
imposta la pagina da visualizzare come contenuto
principale
Una MasterDetailPage contiene proprietà Master e Detail,
entrambe di tipo Page, usate per ottenere e impostare
rispettivamente le pagine master e di dettaglio
54. Master Detail Page (2)
Una MasterDetailPage è un tipo di pagina che che contiene sia le informazioni sulla
pagina master che fa da menu che le informazioni sul dettaglio
Il nodo Master contiene il menu e le informazioni visibili da ognuna delle details page
Il nodo Detail contiene le pagine di dettaglio
Master deve sempre essere un'istanza di ContentPage e Detail deve essere popolata
solo con le istanze TabbedPage, NavigationPage e ContentPage. Ciò contribuirà a
garantire un'esperienza utente coerente su tutte le piattaforme.
55. Es. Master Detail Page (1)
Questo esempio mostra un master detail page con tre pagine
ContactPage
TodoListPage
RemiderPage
Requisiti
Salvare nel progetto android in Resources/drawable le icone menu
contacts.png, todo.png, reminders.png, hamburger.png
56. Es. Master Detail Page (2)
Creare le tre pagine xaml e c# ConatactPagel,
RemiderPage e TodolistPagel, es.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppMasterDetailSimple.ReminderPage">
<ContentPage.Content>
<StackLayout>
<Label Text="Here goes my reminders"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
public partial class ReminderPage : ContentPage
{
public ReminderPage()
{
InitializeComponent();
}
}
.XAML .XAML.cs
57. Es. Master Detail Page (3)
Creare una classe MasterPageItem che conterrà i dati riguardanti
l’ennesimo elemento del menu
public class MasterPageItem
{
public string Title { get; set; }
public string IconSource { get; set; }
public Type TargetType { get; set; }
}
63. TabbedPage
La TabbedPage è costituita da un elenco di schede (Tab)
che impostano un’area di dettaglio
Il modo più semplice di implementare una tabbed page è
di elencare le pagine utilizzate come dettaglio ed i rispettivi
titoli nel nodo TabbedPage.Children
64. Es. TabbedPage (1)
Creo due pagine HomePage e BrowsePage
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppTabbedPage.HomePage">
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to the home page!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppTabbedPage.BrowsePage">
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to the browse page!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
65. Es. TabbedPage (2)
Vado a elencare le pagine ed i rispettivi titoli nella
MainPage come segue
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:AppTabbedPage"
x:Class="AppTabbedPage.MainPage">
<TabbedPage.Children>
<local:HomePage Title="Home"/>
<local:BrowsePage Title="Browse"/>
</TabbedPage.Children>
</TabbedPage>
public partial class MainPage : TabbedPage
{
public MainPage()
{
InitializeComponent();
}
}
MainPage.xam
l
MainPage.xaml.c
s
67. CarouselPage
è costituita da un elenco di pagine che si possono scorrere
trascinando un dito sullo schermo
Si può costruire elencando più nodi ContentPage quante
sono le pagine da realizzare oppure aggiunger un
reference come visto tabbedpage (<local:Anypagename/>
)
68. Es CarouselPage (1)
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:AppCarousel"
x:Class="AppCarousel.MainPage">
<ContentPage>
<StackLayout>
<Label Text="This is a CarouselPage, you can swipe left and right to browse through additional pages." Margin="5" />
<Label Text="Red" HorizontalTextAlignment="Center" HorizontalOptions="FillAndExpand" Margin="5" />
<BoxView Color="Red" VerticalOptions="FillAndExpand" />
</StackLayout>
</ContentPage>
<ContentPage>
<StackLayout>
<Label Text="Green" HorizontalTextAlignment="Center" HorizontalOptions="FillAndExpand" Margin="5" />
<BoxView Color="Green" VerticalOptions="FillAndExpand" />
</StackLayout>
</ContentPage>
<ContentPage>
<StackLayout>
<Label Text="Blue" HorizontalTextAlignment="Center" HorizontalOptions="FillAndExpand" Margin="5" />
<BoxView Color="Blue" VerticalOptions="FillAndExpand" />
</StackLayout>
</ContentPage>
</CarouselPage>
69. Es CarouselPage (2)
public partial class MainPage : CarouselPage
{
public MainPage()
{
InitializeComponent();
}
}
71. Pagine Modali
Una pagina modale richiede agli utenti il completamento di un'attività
indipendente, dalla quale non è possibile spostarsi fino a quando non
viene completata o annullata
La pagine modali sono delle NavigationPage e utilizzano lo stesso
metodo della navigazione gerarchica
Per aprire una pagina modale userò la seguente forma
Navigation.PushModalAsync (new MyModalPage()));
Per chiudere la pagina modale usero la seguente istruzione
await Navigation.PopModalAsync ();
72. Pop Up alert (1)
DisplayAlert ("Alert", "You have been alerted", "OK");
73. Pop Up alert (2)
bool answer = await DisplayAlert ("Question?", "Would you
like to play a game", "Yes", "No");
74. Pop Up alert (3)
string action = await DisplayActionSheet ("ActionSheet:
Send to?", "Cancel", null, "Email", "Twitter", "Facebook");
75. Orientamento del device
Importante considerare come device verrà usato
landscape o potrait
I layout possono essere progettati per supportare
diversi orientamenti usando lo spazio nel migliore dei
modi
A livello di applicazione la rotazione può essere abilitata
o disabilitata
76. Controllo dell’orientamento (1)
I controllo dell’orientamento viene definito al liverllo di
progetto Android o iOS
iOS sono questi impostazione sono memorizzate in un file
info.plist che può essere ediato tramite IDE
77. Controllo dell’orientamento (2)
In android il controllo dell’orientamento definito all’interno
di MainActivity
[Activity(Label = "AppOrientation", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges =
ConfigChanges.ScreenSize | ConfigChanges.Orientation,ScreenOrientation = ScreenOrientation.Landscape)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
78. Xamarin.Android orientation
options
Landscape forza l'orientamento dell'applicazione in landscape, indipendentemente dai dati del sensore.
Portrait forza l'orientamento dell'applicazionea essere protrait , indipendentemente daidati del sensore.
User fa sì che l'applicazione venga presentata utilizzando l'orientamento preferito dell'utente tramite impostazionidel dispositivo
Behind fa sì che l'orientamento dell'applicazionesia lo stesso dell'orientamento dell'actvity.
Sensor l'orientamento dell'applicazioneè dato dal sensore, anche se l'utente ha disabilitatola rotazione automatica.
SensorLandscape l'orientamento dell'applicazione è dato dal sensore e fa sì che che quando lo schermo sia ruotato in landscape i contenuti non vengano mai capovolti.
SensorPortrait l'orientamento dell'applicazione è dato dal sensore e fa sì che che quando lo schermo sia ruotato in portrait i contenuti non vengano mai capovolti.
ReverseLandscape fa sì che quando lo schermosia ruotato in landscape i contenuti vengano capovolti.
ReversePortrait fa sì che quandolo schermo sia ruotato in portrait i contenuti vengano capovolti.
FullSensor l'orientamento dell'applicazione è dato dal sensore e fa sì che che quando lo schermosia ruotato in landscape o in potrait i contenuti nonvengano mai capovolti.
FullUser l'orientamento dell'applicazione è dato dalle preferenze dell’utente e fa sì che che quando loschermo sia ruotato in landscapeo in potrait i contenutinon vengano mai capovolti.
79. Evento cambio orientamento (1)
Xamarin.Forms non offre eventi nello shared code che
indichino il cambiamento di orientamento
Alternativamente è possibile implementare un override del
metodo OnSizeAllocated della classe Page inserendo la
logica conseguente al cambiamento di layout
Il metodo OnSizeAllocated viene chiamato ogni
qualvolta che alla pagina viene assegnata una nuova
dimensione
80. Evento cambio orientamento (2)
private double width = 0;
private double height = 0;
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height); //deve essere chiamato
if (this.width != width || this.height != height)
{
this.width = width;
this.height = height;
//qui posso eseguire istruzioni per reagire al
//cambiamento di orientamento
}
}
81. Evento cambio orientamento (3)
Prestare attenzione ai rapporti: i cambiamenti di orientamento
possono causare problemi quando vengono inserite dimensioni
in rapporto. Ad esempio, una vista che avrebbe molto spazio
con 1/3 dello spazio verticale di uno schermo in portrait
potrebbe non adattarsi a 1/3 dello spazio verticale in landscape.
Fai attenzione ai valori assoluti - i valori assoluti (pixel) che
hanno senso nel portrait potrebbero non avere senso
landscape
82. Es. Controllo layout al
cambiamento di orientamento (1)
Nel progetto android
Impostare ScreenOrientation = ScreenOrientation.FullSensor
Salvare nella cartella Resources/drawble l’immagine lion.png
84. Es. Controllo layout al
cambiamento di orientamento (3)
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private double width = 0;
private double height = 0;
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height); //must be called
if (width != this.width || height != this.height)
{
this.width = width;
this.height = height;
if (width > height)
{
outerStack.Orientation = StackOrientation.Horizontal;
}
else
{
outerStack.Orientation = StackOrientation.Vertical;
}
}
}
}
85. Es. Controllo layout al
cambiamento di orientamento (4)
outerStack viene regolato per presentare l'immagine e i
controlli nello StackLayout orizzontale o verticale a
seconda dell'orientamento, per sfruttare al meglio lo spazio
disponibile.
87. WebView
La WebView è un view dedicata a mostrare contenuti HTML nelle app
Le WebView supportano seguenti contenuti
HTML & CSS websites: le webview hanno il supporto completo per HTML e CSS, mentre un
supporto limitato per il javascript
Documenti: visualizzazione di documenti
HTML strings: le web view possono mostrare stringhe html caricate dalla memoria
Local Files: le WebView possono mostrare ogni contenuto embedded delle nostre app
88. HTML & CSS websites
Per visualizzare un sito Web da Internet, impostare la
proprietà Source di WebView con una URL
89. Es. HTML & CSS websites
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var browser = new WebView();
browser.Source = "http://xamarin.com";
Content = browser;
}
}
90. HTML strings
Se si vuole presentare una stringa di HTML definita
dinamicamente nel codice, sarà necessario creare
un'istanza di HtmlWebViewSource e impostare la
stringa html come valore della property html
91. Es . HTML strings
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var browser = new WebView();
var htmlSource = new HtmlWebViewSource();
htmlSource.Html = @"<!DOCTYPE html>
<html>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>";
browser.Source = htmlSource;
Content = browser;
}
}
92. Es. Local HTML Content (1)
salvare nella cartella Assets l’immagine XamarinLogo.png
salvare nella cartella Assets il file default.css e local.html
come segue
html, body {
margin: 0;
padding: 10;
}
body, p, h1 {
font-family: Arial;
font-size:20px;
font-weight:bold;
}
<html>
<head>
<title>Xamarin Forms</title>
</head>
<body>
<h1>Xamrin.Forms</h1>
<p>This is another android local web page.</p>
<img src="XamarinLogo.png" />
</body>
</html>
93. Es. Local HTML Content (2)
Nel progetto PCL aggiungere l’interfaccia IBaseUrl e nel progetto Android la sua
implementazione
public interface IBaseUrl { string Get(); }
using Xamarin.Forms;
using AppLocalHtmlContent.Droid;
[assembly: Dependency(typeof(BaseUrl_Android))]
namespace AppLocalHtmlContent.Droid
{
public class BaseUrl_Android : IBaseUrl
{
public string Get()
{
return "file:///android_asset/";
}
}
}
IBaseUrl.c
s
BaseUrl_Android.c
s
94. Es. Local HTML Content (3)
Nel progetto PCL impostare la MainPage.cs.xml come
segue public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var browser = new WebView();
var htmlSource = new HtmlWebViewSource();
htmlSource.Html = @"<html>
<head>
<link rel=""stylesheet"" href=""default.css"">
</head>
<body>
<h1>Xamarin.Forms</h1>
<p>The CSS and image are loaded from local files!</p>
<img src='XamarinLogo.png'/>
<p><a href=""local.html"">next page</a></p>
</body>
</html>";
htmlSource.BaseUrl = DependencyService.Get<IBaseUrl>().Get();
browser.Source = htmlSource;
Content = browser;
}
96. Dependency Service (1)
Visto che abbiamo BaseUrl diverse per ogni piattaforma
dobbiamo utilizzare DependencyService
DependencyService serve sopratutto quando abbiamo
delle parti di applicazione fortemente dipendenti della
piattaforma
Si definisce l’interfaccia nel PCL es. IBaseUrl e la si va
ad implementare nel progetto della piattaforma
specifico es. BaseUrl_Android
97. Dependency Service (2)
Le registrazione dell’interfaccia avviene tramite decoration [assembly:
Dependency(typeof(nome_classe))]
es. [assembly: Dependency(typeof(BaseUrl_Android))]
La richiesta di un’instanza della classe implementata avviene tramite metodo Get
DependencyService.Get<nome_interfaccia>().Get()
es. DependencyService.Get<IBaseUrl>().Get();
A runtime a seconda della piattaforma verrà cercata la classe che implementa l’interfaccia
desiderata