Как-то совершенно незаслуженно обделена вниманием платформа Xamarin 2.0, и я б хотел начать описание всех его замечательных свойств
Прежде всего, что такое Xamarin?
Xamarin это коммерческий продукт, основанный на open-source проекте Mono, который позволяет использовать .Net framework, в том числе язык C#, для кроссплатформенных разработок.
Основные свойства:
- C# для написания приложений под Android, iOs и Windows8. Поддержка LINQ и async/task
- Native UI, Native Peformance — код компилируется под конкретную платформу и использует native UI контроли
- Visual Studio и все его plugins, включая ReSharper, NUnit testing…
- Xamarin Studio, которая похожа на Visual Studio, но доступна также и для Mac
- Использование .Net библиотек
- Использование других готовых native компонент, обвернутых в C#
- Графический редактор для Андроида
MvvmCross
В этом примере я буду использовать модель MVVM, для тех кто с ней не знаком, то вкратце цитата из википедии:
Паттерн MVVM делится на три части:
Модель (Model), так же, как в классической MVC, Модель представляет собой фундаментальные данные, необходимые для работы приложения.
Вид/Представление (View) — это графический интерфейс, то есть окно, кнопки и.т.п. Вид является подписчиком на событие изменения значений свойств или команд, предоставляемых Моделью Вида. В случае, если в Модели Вида изменилось какое-либо свойство, то она оповещает всех подписчиков об этом, и Вид в свою очередь запрашивает обновленное значение свойства из Модели Вида. В случае, если пользователь воздействует на какой-либо элемент интерфейса, Вид вызывает соответствующую команду, предоставленную Моделью Вида.
Модель вида (ViewModel, что означает «Model of View»[1]) является с одной стороны абстракцией Вида, а с другой предоставляет обертку данных из Модели, которые подлежат связыванию. То есть она содержит Модель, которая преобразована к Виду, а также содержит в себе команды, которыми может пользоваться Вид, чтобы влиять на Модель.
Для кроссплатформенной имплементации этого шаблона, лучшей библиотекой (к тому же open source) является MvvmCross. Ее разработчик замечательно ее поддерживает и практически мгновенно откликается на любой вопрос.
Начнем
Для примера мы создадим простое приложение для подсчета чаевых. В зависимости от нашей щедрости и суммы счета она подсчитает размер чаевых, которые мы хотим оставить.
Установка
Прежде всего, нам необходимо зарегистрироваться и установить Xamarin Studio. Сам шаг довольно таки простой, никаких проблем я не заметил. Автоматически установятся Java, ADT, plugin для Visual Studio и библиотеки Mono.
Создание проекта
Почти любое приложение будет содержать несколько проектов.
- Один из них будет 'core', который будет кроссплатформенный и содержать как можно больше кода: view models, общение с сервером, протоколы, обьекты даты и т.д.
- UI проект для каждой платформы. Этот код не может быть общим, так как в нем используются компоненты, специфичные для платформы
Создаем New Project в Visual Studio, выбираем Visual C#, Windows, Portable Class Library.
Создаем проект TipCalc.Core и solution TipCalc. Выбираем опцию Windows Phone 7.5 and higher.
Хочу заметить, что пока поддерживается только версия .Net 4.0, но это должно измениться буквально в этом месяце.
Удаляем Class1.cs, он никому не нужен
Добавляем библиотеку MvvmCross через NuGet. Для примера мы выберем Hot Tuna Start Pack, который включает в себя несколько начальных файлов.
Важно убедиться, что установлена последняя версия NuGet Package Manager, как минимум 2.5
После успешной установки мы увидим два новых файла: App.cs, в котором производится начальная инициализация MvvmCross, и файл FirstViewModel.cs в папке ViewModels. С точки зрения правильного программирования, я должен переименовать имя класса FirstViewModel на TipViewModel, но для упрощения примера так и оставим.
FirstViewModel класс наследует от MvxViewModel, это класс библиотеки MvvmCross и позволяет нам в дальнейшем посылать сообщения UI, когда данные изменились. Этот класс имплементирует INotifyPropertyChanged и его аналогия в WPF это BaseViewModel.
Добавим в этот класс 3 свойства: SubTotal (сумма счета), Generosity (щедрость) и Tip (чаевые, которые мы оставим). И перерасчет чаевых, в зависимости от них:
using Cirrious.MvvmCross.ViewModels;
namespace TipCalc.Core.ViewModels
{
public class FirstViewModel
: MvxViewModel
{
public FirstViewModel()
{
}
public override void Start()
{
_subTotal = 100;
_generosity = 10;
Recalcuate();
base.Start();
}
private double _subTotal;
public double SubTotal
{
get { return _subTotal; }
set { _subTotal = value; RaisePropertyChanged(() => SubTotal); Recalcuate(); }
}
private int _generosity;
public int Generosity
{
get { return _generosity; }
set { _generosity = value; RaisePropertyChanged(() => Generosity); Recalcuate(); }
}
private double _tip;
public double Tip
{
get { return _tip; }
set { _tip = value; RaisePropertyChanged(() => Tip);}
}
private void Recalcuate()
{
Tip = SubTotal * ((double)Generosity) / 100.0;
}
}
}
Компилируем, ура, библиотека 'core' готова.
Клиент на Андроиде
Теперь мы хотим увидеть нашу логику на живом экране/телефоне/планшете. Так будет выглядеть его эскиз:
В том же solution добавим новый проект, но его тип будет Android -> Android Application. Назовем его TipCalc.UI.Droid
Если все нормально установлено, то мы увидим такую картинку:
Удаляем Activity1.cs и Main.axml из проекта.
Добавляем точно также, через NuGet, тот же пакет MvvmCross — Hot Tuna Starter Pack. Мы увидим в проекте новые файлы:
- SplashScreen.cs — начальный Activity для аппликации
- Setup.cs — иницализация MvvmCross и привязки ее к 'core'
- FirstView.cs — Activity для нашего FirstViewModel
- FirstView.axml — и его layout
Добавим в reference проект TipCalc.Core.csproj
Теперь мы нарисуем сами контроли.
Для этого откроем FirstView.axml и отредактируем его или в графическом редакторе или в xml редакторе. Мы добавим туда LinearLayout, TextView, EditText, SeekBar.
Через MvxBind мы свяжем свойства контроля с свойством нашего ViewModel.
Должна получиться вот такая картинка:
Если мы напишем такой код:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/TipCalc.UI.Droid"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="SubTotal" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
local:MvxBind="Text SubTotal" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Generosity" />
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="40"
local:MvxBind="Progress Generosity" />
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#ffff00" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Tip to leave" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
local:MvxBind="Text Tip" />
</LinearLayout>
Важно заметить как мы делаем связывания свойств контролей. Свойство Text элемента TextView связывается (двусторонне) с свойством Tip нашего класса FirstViewModel посредством строчки local:MvxBind=«Text Tip» внутри самого описания контроля. Во всем остальном файл axml абсолютно идентичен любому layout в Андроиде.
Сохраняем, компилируем и запускаем. Вуаля, мы меняем сумму счета или нашу щедрость и чаевые автоматически меняются.
Итоги
- Мы установили Xamarin Studio
- Мы построили кроссплатформенную библиотеку с общей логикой
- Мы создали приложение для Андроида, которая общается с логикой посредством MvvmCross (в этом нет необходимости, но Mvvm это круто)
Что мы упустили
- Как работает Xamarin
- Что такое Mvvm, как это имплементировано в MvvmCross и какие дополнительные возможности мы можем получить
- Мы не построили примеры для iOs и Windows8
- И много много другого
Источники
Xamarin
MvvmCross project
MvvmCross tutorial
MvvmCross tutorial video
Автор: Don_Eric