Aller au contenu

Feuille de chaleur Xamarin

Xamarin - Forme transversale Applications mobiles avec .NET

Xamarin est une plateforme open-source pour construire des applications modernes et performantes pour iOS, Android et Windows avec .NET. Xamarin est une couche d'abstraction qui gère la communication de code partagé avec le code de plate-forme sous-jacent.

Copier toutes les commandes Générer PDF

Sommaire

  • [Installation] (#installation)
  • [Pour commencer] (#getting-started)
  • [Structure du projet] (#project-structure)
  • [Xamarin.Formulaires] (#xamarinforms)
  • [Xamarin.Native] (#xamarinnative)
  • [XAML] (#xaml)
  • [Raccordement des données] (#data-binding)
  • [Navigation] (#navigation)
  • [Service de dépannage] (#dependencyservice)
  • [Requérants sur mesure] (#custom-renderers)
  • [Effets] (#effects)
  • [Centre de mesure] (#messagingcenter)
  • [Persistance des données] (#data-persistence)
  • [Réseau] (#networking)
  • [Essais] (#testing)
  • [Déploiement] (#deployment)
  • [Meilleures pratiques] (#best-practices)
  • [Dépannage] (#troubleshooting)

Installation

Préalables

# 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

Vérifier l'installation

# 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
```_

## Commencer

### 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)
```_

### Lancer l'application
```bash
# Select a startup project (Android or iOS)
# Choose a device or emulator
# Click the "Run" button or press F5

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. Formulaires

Pages

// 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());
    }
}

Mise en page

// 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) } }
};

Contrôles

// 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" }
};

Xamarin. Autochtones

Xamarin. Android

// 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();
        };
    }
}

C'est ce qu'il a dit.

// 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);
    }
}

XAML

<!-- 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");
    }
}

Reliure des données

<!-- 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}" />
// 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();

Service de dépendance

// 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!");

Distributeurs personnalisés

// 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);
            }
        }
    }
}

Effets

// 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>

Centre de messagerie

// 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");

Persistance des données

Préférences

// Set a value
Preferences.Set("my_key", "my_value");

// Get a value
var value = Preferences.Get("my_key", "default_value");

Système de fichiers

// 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

// 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éseautage

HttpClient

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);
}

Réfrigérer

// 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();

Essais

Essai en unité

// 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);
}

Test d'assurance-chômage

// 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.");
}

Déploiement

Android

# Build the app in Release mode
# Archive the app
# Distribute the archive (e.g., to Google Play)

iOS

# Build the app in Release mode
# Archive the app
# Distribute the archive (e.g., to the App Store)

Meilleures pratiques

  • Utilisez MVVM: Séparez votre UI de votre logique d'entreprise.
  • Utilisez la liaison des données: Simplifiez votre code d'interface utilisateur et rendez-le plus durable.
  • Utiliser le service de dépendance pour un code spécifique à la plateforme: Gardez votre code partagé propre.
  • Optimiser les performances: Utilisez des fixations compilées, un chargement paresseux et d'autres techniques.
  • Essais d'écriture: Assurez-vous que votre application fonctionne correctement.

Dépannage

Questions communes

  • ** Erreurs de construction**: Vérifiez vos chemins SDK et vos paquets NuGet.
  • ** Erreurs de déploiement**: Vérifiez vos clés de signature et vos profils de provisionnement.
  • ** Erreurs dans le temps**: Utilisez le débogueur et vérifiez les journaux de l'appareil.

Résumé

Xamarin est une plateforme puissante pour la construction d'applications mobiles multiplateforme avec .NET. Ses principales caractéristiques sont les suivantes :

  • Native Performance: Les applications Xamarin sont compilées en code natif.
  • Native UI: Xamarin donne accès aux contrôles d'assurance-chômage natifs.
  • Code partagé: Partagez jusqu'à 90 % de votre code sur toutes les plateformes.
  • .NET Ecosystem: Tirer parti de la puissance de la plateforme .NET et de son écosystème.
  • Visual Studio: Utilisez le puissant IDE Visual Studio pour le développement.

Xamarin est un excellent choix pour . Les développeurs NET qui veulent construire des applications mobiles multiplateforme sans apprendre de nouveaux langages ou cadres.