Aide-mémoire Xamarin
Xamarin - Cross-Platform Mobile Apps with .NET
Xamarin est une plateforme open-source pour créer des applications modernes et performantes pour iOS, Android et Windows avec .NET. Xamarin est une couche d'abstraction qui gère la communication du code partagé avec le code de plateforme sous-jacent.
(This section appears to be empty in the original text, so no translation is needed)Table des matières
- Installation
- Démarrage
- Structure du projet
- Xamarin.Forms
- Xamarin.Native
- XAML
- Liaison de données
- Navigation
- DependencyService
- Rendus personnalisés
- Effets
- MessagingCenter
- Persistance des données
- Mise en réseau
- Tests
- Déploiement
- Meilleures pratiques
- Résolution des problèmes
Installation
Prérequis
# Install Visual Studio (Windows) or Visual Studio for Mac (macOS)
# Make sure to include the "Mobile development with .NET" workload
# For iOS development on Windows, you need a Mac with Xcode and Visual Studio for Mac installed
```(No text provided for translation)
### Vérifier l'installation
```bash
# Open Visual Studio Installer
# Check if "Mobile development with .NET" is installed
# Check for Android SDK and NDK
# Visual Studio > Tools > Options > Xamarin > Android Settings
# Check for Xcode and Apple SDKs (macOS)
# Visual Studio for Mac > Preferences > Projects > SDK Locations > Apple
```(No text provided for translation)
## Démarrage
### Créer un nouveau projet
```bash
# In Visual Studio
# File > New > Project
# Select "Mobile App (Xamarin.Forms)"
# Choose a template (Blank, Tabbed, Shell)
# In Visual Studio for Mac
# File > New Solution
# Select "Multiplatform > App > Xamarin.Forms"
# Choose a template (Blank, Tabbed, Shell)
```(No text provided for translation)
### Exécuter l'application
```bash
# Select a startup project (Android or iOS)
# Choose a device or emulator
# Click the "Run" button or press F5
```(No text provided for translation)
## Structure du projet
MyApp/ ├── MyApp/ # .NET Standard library (shared code) │ ├── App.xaml │ ├── App.xaml.cs │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── Models/ │ ├── Views/ │ ├── ViewModels/ │ └── Services/ ├── MyApp.Android/ # Android-specific project │ ├── MainActivity.cs │ ├── Resources/ │ └── Assets/ ├── MyApp.iOS/ # iOS-specific project │ ├── AppDelegate.cs │ ├── Main.cs │ └── Info.plist └── MyApp.sln # Solution file
## Xamarin.Forms
### Pages
```csharp
// ContentPage
public class MyContentPage : ContentPage
{
public MyContentPage()
{
Content = new StackLayout
{
Children = { new Label { Text = "Welcome to Xamarin.Forms!" } }
};
}
}
// TabbedPage
public class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
Children.Add(new MyContentPage { Title = "Tab 1" });
Children.Add(new MyContentPage { Title = "Tab 2" });
}
}
// FlyoutPage (Master-Detail)
public class MyFlyoutPage : FlyoutPage
{
public MyFlyoutPage()
{
Flyout = new ContentPage { Title = "Menu" };
Detail = new NavigationPage(new MyContentPage());
}
}
```(No text provided for translation)
### Mises en page
```csharp
// StackLayout
new StackLayout
{
Orientation = StackOrientation.Vertical,
Spacing = 10,
Children = { new Label(), new Button() }
};
// Grid
new Grid
{
RowDefinitions = { new RowDefinition { Height = GridLength.Auto } },
ColumnDefinitions = { new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) } },
Children = { { new Label(), 0, 0 } }
};
// FlexLayout
new FlexLayout
{
Direction = FlexDirection.Row,
JustifyContent = FlexJustify.SpaceBetween,
Children = { new Label(), new Button() }
};
// AbsoluteLayout
new AbsoluteLayout
{
Children = { { new BoxView { Color = Colors.Blue }, new Rectangle(0, 0, 100, 100) } }
};
// RelativeLayout
new RelativeLayout
{
Children = { { new BoxView(), Constraint.Constant(0) } }
};
```(No text provided for translation)
### Contrôles
```csharp
// Label
new Label { Text = "Hello, Xamarin!", FontSize = 24 };
// Button
new Button { Text = "Click Me", Command = new Command(() => DisplayAlert("Title", "Message", "OK")) };
// Entry
new Entry { Placeholder = "Enter text" };
// Editor
new Editor { Placeholder = "Enter multi-line text" };
// SearchBar
new SearchBar { Placeholder = "Search..." };
// Slider
new Slider { Minimum = 0, Maximum = 100 };
// Stepper
new Stepper { Minimum = 0, Maximum = 10 };
// Switch
new Switch { IsToggled = true };
// DatePicker
new DatePicker();
// TimePicker
new TimePicker();
// ListView
new ListView
{
ItemsSource = new[] { "Item 1", "Item 2" },
ItemTemplate = new DataTemplate(() =>
{
var cell = new TextCell();
cell.SetBinding(TextCell.TextProperty, ".");
return cell;
})
};
// CollectionView
new CollectionView
{
ItemsSource = new[] { "Item 1", "Item 2" }
};
```(No text provided for translation)
## Xamarin.Native
### Xamarin.Android
```csharp
// MainActivity.cs
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
var button = FindViewById<Button>(Resource.Id.myButton);
button.Click += (sender, e) =>
{
Toast.MakeText(this, "Button Clicked!", ToastLength.Short).Show();
};
}
}
```(No text provided for translation)
### Xamarin.iOS
```csharp
// ViewController.cs
public partial class ViewController : UIViewController
{
public ViewController(IntPtr handle) : base(handle) { }
public override void ViewDidLoad()
{
base.ViewDidLoad();
var button = new UIButton(UIButtonType.System);
button.Frame = new CGRect(20, 200, 280, 44);
button.SetTitle("Click Me", UIControlState.Normal);
button.TouchUpInside += (sender, e) =>
{
var alert = UIAlertController.Create("Title", "Message", UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
PresentViewController(alert, true, null);
};
View.AddSubview(button);
}
}
```(No text provided for translation)
## XAML
```xml
<!-- MainPage.xaml -->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.MainPage">
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<Button Text="Click Me" Clicked="OnButtonClicked" />
</StackLayout>
</ContentPage>
// MainPage.xaml.cs
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void OnButtonClicked(object sender, EventArgs e)
{
DisplayAlert("Title", "Message", "OK");
}
}
```(No text provided for translation)
## Liaison de données
```xml
<!-- ViewModel -->
public class MyViewModel : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<!-- XAML -->
<ContentPage.BindingContext>
<local:MyViewModel />
</ContentPage.BindingContext>
<Entry Text="{Binding Name, Mode=TwoWay}" />
<Label Text="{Binding Name}" />
```(No text provided for translation)
## Navigation
```csharp
// Push a new page
await Navigation.PushAsync(new DetailsPage());
// Pop a page
await Navigation.PopAsync();
// Pop to root
await Navigation.PopToRootAsync();
// Pass data
await Navigation.PushAsync(new DetailsPage(item));
// Modal navigation
await Navigation.PushModalAsync(new ModalPage());
await Navigation.PopModalAsync();
```(No text provided for translation)
## DependencyService
```csharp
// Define an interface in shared code
public interface ITextToSpeech
{
void Speak(string text);
}
// Implement the interface in platform-specific projects
// Android
[assembly: Dependency(typeof(TextToSpeech_Android))]
namespace MyApp.Droid
{
public class TextToSpeech_Android : ITextToSpeech { ... }
}
// iOS
[assembly: Dependency(typeof(TextToSpeech_iOS))]
namespace MyApp.iOS
{
public class TextToSpeech_iOS : ITextToSpeech { ... }
}
// Use the service in shared code
DependencyService.Get<ITextToSpeech>().Speak("Hello, Xamarin!");
```(No text provided for translation)
## Rendus personnalisés
```csharp
// Create a custom control in shared code
public class MyEntry : Entry { }
// Create a custom renderer in platform-specific projects
// Android
[assembly: ExportRenderer(typeof(MyEntry), typeof(MyEntryRenderer))]
namespace MyApp.Droid
{
public class MyEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.SetBackgroundColor(Android.Graphics.Color.LightGreen);
}
}
}
}
// iOS
[assembly: ExportRenderer(typeof(MyEntry), typeof(MyEntryRenderer))]
namespace MyApp.iOS
{
public class MyEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.BackgroundColor = UIColor.FromRGB(204, 153, 255);
}
}
}
}
```(No text provided for translation)
## Effets
```csharp
// Create an effect in shared code
public class FocusEffect : RoutingEffect
{
public FocusEffect() : base("MyApp.FocusEffect") { }
}
// Implement the effect in platform-specific projects
// Android
[assembly: ResolutionGroupName("MyApp")]
[assembly: ExportEffect(typeof(FocusEffect_Android), "FocusEffect")]
namespace MyApp.Droid
{
public class FocusEffect_Android : PlatformEffect { ... }
}
// Use the effect in XAML
<Entry>
<Entry.Effects>
<local:FocusEffect />
</Entry.Effects>
</Entry>
```(No text provided for translation)
## MessagingCenter
```csharp
// Subscribe to a message
MessagingCenter.Subscribe<MainPage, string>(this, "Hi", (sender, arg) =>
{
// Do something with the message
});
// Send a message
MessagingCenter.Send(this, "Hi", "John");
// Unsubscribe
MessagingCenter.Unsubscribe<MainPage, string>(this, "Hi");
```(No text provided for translation)
## Persistance des données
### Préférences
Note: Only texts 1 and 2 contained actual content to translate. The rest of the sections were empty in the original text.```csharp
// Set a value
Preferences.Set("my_key", "my_value");
// Get a value
var value = Preferences.Get("my_key", "default_value");
```### Système de Fichiers
```csharp
// Get the local app data folder
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var filename = Path.Combine(path, "myfile.txt");
// Write to a file
File.WriteAllText(filename, "Hello, Xamarin!");
// Read from a file
var content = File.ReadAllText(filename);
```### SQLite
```csharp
// Install sqlite-net-pcl NuGet package
// Create a model
public class MyItem
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string Text { get; set; }
}
// Create a database connection
var db = new SQLiteAsyncConnection(dbPath);
await db.CreateTableAsync<MyItem>();
// Save an item
await db.InsertAsync(item);
// Get all items
var items = await db.Table<MyItem>().ToListAsync();
```## Réseau
```csharp
var client = new HttpClient();
var response = await client.GetAsync("https://api.example.com/items");
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var items = JsonConvert.DeserializeObject<List<MyItem>>(content);
}
```### HttpClient
```csharp
// Install Refit NuGet package
// Define an interface
public interface IMyApi
{
[Get("/items")]
Task<List<MyItem>> GetItems();
}
// Use the interface
var api = RestService.For<IMyApi>("https://api.example.com");
var items = await api.GetItems();
```### Refit
```csharp
// Use a testing framework like NUnit or xUnit
[Test]
public void MyViewModel_MyCommand_ShouldDoSomething()
{
// Arrange
var viewModel = new MyViewModel();
// Act
viewModel.MyCommand.Execute(null);
// Assert
Assert.IsTrue(viewModel.MyProperty);
}
```## Tests
```csharp
// Use Xamarin.UITest
[Test]
public void AppLaunches()
{
app.Screenshot("First screen.");
}
[Test]
public void TappingButton_ShouldNavigateToDetails()
{
app.Tap(c => c.Button("MyButton"));
app.WaitForElement(c => c.Marked("DetailsPage"));
app.Screenshot("Details screen.");
}
```### Tests Unitaires
```bash
# Build the app in Release mode
# Archive the app
# Distribute the archive (e.g., to Google Play)
```### Tests d'Interface Utilisateur
```bash
# Build the app in Release mode
# Archive the app
# Distribute the archive (e.g., to the App Store)
```## Déploiement