version : 1.0 - 30/08/2020.
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}" />
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 image 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; }
}
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);
Pour appeller 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>
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>
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));
}
}