Xamarin.Forms

De BdC de chez Wam...

Divers

Déverrouillage “http”

Par défaut les application android n’autorise pas la communication avec des sites non sécurisé (qui n’utilisent pas “https”). Pour pallier à cette configuration il faudra modifier le fichier “properties/AndroidManifest.xml”. Objet application du fichier d’origine : <application android:label="PizzaApp.Android" android:theme="@style/MainTheme"></application>.

Objet application modifié pour permettre la connexion aux sites “http” : <application android:label="PizzaApp.Android" android:theme="@style/MainTheme" android:usesCleartextTraffic="true"></application>. C’est le paramètre android:usesCleartextTraffic=“true” qui autorise cette connexion.

Style

Imposer le même style à des items. L’exemple suivant gère un style pour un bouton. Le style est déclaré dans la fichier : “App.xaml”.

Dans le fichier App.xaml.

<ResourceDictionary>
<Style TargetType="NavigationPage" ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="White" />
<Setter Property="BarBackgroundColor" Value="#4e89a3"/>
<Setter Property="BarTextColor" Value="White"/>
</Style>
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="White" />
</Style>
<Style x:Key="boutonLabStyle" TargetType="Button">
<Setter Property="BackgroundColor" Value="#518faa" />
<Setter Property="TextColor" Value="White" />
</Style>
</ResourceDictionary>

Et dans le fichier nomDeLaPage.xaml, la mise en forme est la suivante :

<Button Text="Compter"
VerticalOptions="Center"
Clicked="CountButtonClick"
Style="{StaticResource boutonLabStyle}" />

Splash

Afficher une image durant le chargement de l’application.

Dans le fichier Resources/values/styles.xlm :

<style name="splashscreen" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@drawable/splash</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowIsFloating">false</item>
<item name="android:backgroundDimEnabled">true</item>
</style>

Les images qui sont représentées dans “@drawable/splash” sont des images “splash.9.png” se trouvant dans les répertoires “drawable”.

Dans le fichier MainActivity.cs il faut rajouté les lignes suivantes :

[Activity(Label = "Pizza", Icon = "@mipmap/icon", Theme = "@style/splashscreen", MainLauncher = true, NoHistory = true)]
public class SplashActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnResume()
{
base.OnResume();
StartActivity(typeof(MainActivity));
}
}

ATTENTION : Il faut passer à “false” le paramètre “MainLauncher” de “l’Activity” initiale. Et effacer les paramètres “Label” et “Icon” de cette “Activity” iniitiale.

ListView

Pour créer une liste, le code suivant doit être incorporé dans la page “nomDeLaPage.xaml” :

<ListView x:Name="maListView" RowHeight="30">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="Center" Margin="15, 0">
<Label Text="{Binding Nom}" HorizontalOptions="FillAndExpand" TextColor="Black"/>
<Label Text="{Binding Prix}" FontAttributes="Bold" TextColor="Black"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Le code suivant est à intégrer dans le constructeur de la page “nomDeLaPage.cs” :

articles = new List<Article>();
articles.Add(new Article { Nom = "Lait", Prix = "4€", Description = "Pack de 6." });
articles.Add(new Article { Nom = "Chocolat", Prix = "4.85€", Description = "Au lait ou au noisettes." });
articles.Add(new Article { Nom = "Biscuit", Prix = "5.12€", Description = "Ils sont bons." });
articles.Add(new Article { Nom = "Emmental", Prix = "3.5€", Description = "Durée 6 mois." });
articles.Add(new Article { Nom = "Oeuf", Prix = "2.2€", Description = "Paquet de 6." });

maListView.ItemsSource = articles;

maListView.ItemSelected += (sender, e) =>
{
if (maListView.SelectedItem != null)
{
Article article = maListView.SelectedItem as Article;

DisplayAlert(article.Nom, article.Description, "OK");
maListView.SelectedItem = null;
}
};

La classe “Article” est la suivante :

public class Article
{
public string Nom { get; set; }
public string Prix { get; set; }
public string Description { get; set; }
}

NavigationPage

Création d’une navigation

La création d’une navigation se fait dans le fichier “App.xaml.cs”. Il faut remplacer la ligne suivant :

MainPage = new WelcomePage();

par celle-ci :

MainPage = new NavigationPage(new WelcomePage());

IMPORTANT Si on ne veut pas d’une navigation de style “menu”, il faut mettre la ligne suivante dans les codes constructeurs de TOUTES les pages :

// Suppression de la "Navigation Bar"
NavigationPage.SetHasNavigationBar(this, false);

Appel d’une nouvelle page

Pour appeler une nouvelle page, le code est le suivant :

Navigation.PushAsync(new nomNouvellePage(parametreSiExistant));

Logiquement, dans une compilation classique, “parametreSiExistant” n’existe pas. Si il est nécessaire, il va falloir modifier la ligne d’en-tête du constructeur de la nouvelle page. Un constructeur classique' a pour première ligne :

public NomPage()

Pour un constructeur d’une page demandant un ou des paramètres le code de début du constructeur sera le suivant :

public NomPage() : this(5)
{
}
 
public NomPage(int parametreSiExistant)

Cela permet de visualiser correctement la page dans le “visualisateur”.

Retour à la page précédente

Pour ce faire, utilisation du code suivant Navigation.PopAsync();. ## Retour à la page initiale Pour ce faire, utilisation du code suivant :

Navigation.PopToRootAsync();

Personalisation de la barre de navigation

L’exemple du code suivant donne une possibilité de personnaliser la barre de menu de la navigation.

<NavigationPage.TitleView>
<StackLayout HorizontalOptions="Center"
Margin="{OnPlatform iOS='0,0,25,0', Android='0,0,20,0', Default=0}"
Orientation="Horizontal">

<Image Source="pizza_logo.png" HeightRequest="40" />
<Label Text="Pizzas"
FontAttributes="Bold"
TextColor="White" VerticalOptions="Center" />
</StackLayout>
</NavigationPage.TitleView>

Tache Asynchrone

La création d’une tâche asynchrone s’exécute à partir du code suivant (en exemple) :

private async Task NomDeLaFonction()
{
await Task.Delay(3000);
await Navigation.PopToRootAsync();
}

Le mot clé “await” va faire en sorte que chaque ligne s’exécutera lorsque la précédente sera, entièrement, terminée.

Pour info : await Task.Delay(3000); permet d’attendre sans rien faire 3s.

Grid

Exemple de création d’un GridLayout :

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<BoxView BackgroundColor="{StaticResource shadowColor}"
Grid.Row="2"
Grid.Column="0"
Rotation="-10"
Margin="-20, 0, -20, -35"
HeightRequest="120"/>

<StackLayout Grid.Row="1" Grid.Column="0" VerticalOptions="Center">
<Label Text="Devinez le"
TextColor="{StaticResource titleColor}"
FontSize="30"
HorizontalOptions="Center"/>
</StackLayout>
</Grid>

JSON

Pour gérer des donner Json il faut intégrer le paquet : Newtonsoft.Json.

Exemple de désérialisation d’une chaine Json contenant un tableau d’objet “Pizza” :

pizzas = JsonConvert.DeserializeObject<List<Pizza>>(pizzasJson);

Téléchargement asynchrone

Le code suivant permet à une application de télécharger des datas de façon asynchrone.

public MainPage()
{
InitializeComponent();

listView.RefreshCommand = new Command((obj) => {
DownloadData((pizzas) =>
{
listView.ItemsSource = pizzas;

listView.IsRefreshing = false;
});
});

listView.IsVisible = false;
waitLayout.IsVisible = true;

DownloadData((pizzas) =>
{
listView.ItemsSource = pizzas;

listView.IsVisible = true;
waitLayout.IsVisible = false;
});
}

public void DownloadData(Action<List<Pizza>> action)
{
const string URL = "https://drive.google.com/uc?export=download&id=13B0krp-ajtf-SGL9Ia1xKy1lKK2aCq4l";
using (var webclient = new WebClient())
{
// Le téléchargement asynchrone est terminé jusqu'à présent, il ne s'est rien passé...
webclient.DownloadStringCompleted += (object sender, DownloadStringCompletedEventArgs e) =>
{
try
{
string pizzasJson = e.Result;

List<Pizza> pizzas = JsonConvert.DeserializeObject<List<Pizza>>(pizzasJson);

// La "listView" est un composant graphique, mais à ce niveau, le prog
// est dans une thread reseau... d'ou l'appel à : Device.BeginInvokeOnMainThread(()
Device.BeginInvokeOnMainThread(() =>
{
action.Invoke(pizzas);
});
}
catch (Exception ex)
{
Device.BeginInvokeOnMainThread(() =>
{
DisplayAlert("ERREUR", "Une erreur réseau s'est produite : " + ex.Message + ".", "OK");
action.Invoke(null);
});
}
};
 
// Lancement d'un téléchargement asynchrone
webclient.DownloadStringAsync(new Uri(URL));
}
}