Как стать автором
Обновить

Комментарии 9

Любопытно.
Сам я чисто десктопный code-monkey, но порывался освоить андроид пару раз, в т.ч. Xamarin. Оба раза бросал это дело, потерпев неудачу с hello world (в окне с полем ввода и кнопкой элементы наезжали друг на друга и растащить их не удавалось).
В третий раз попробовать, что ли…
Начните с WPF и MVVM, будет намного проще.

Аналогичная ситуация была, в качестве хобби делал одностраничные програмки на WinForm для автоматизации рутины. В первое время отталкивало отсутствие визуального редактора, для каждого изменения необходимо было заново билдить приложение, что отнимает не мало времени. В прошлом году появилась отличная фича — XAML Hot Reload, позволяющая изменять разметку XAML во время выполнения приложения, что экономит кучу времени.
Начните с самого простого расположения — StackLayout, когда элементы располагаются друг за другом, после попробовать Grid. Для более сложной разметки комбинацию данных слоев.

Если Microsoft не станет продвигать Xamarin ещё активнее, то в ближайшие 10 лет, он просто канет в лету.


Правду же говорят: Xamarin — хорошо подходит для MVP, а не для конечного продукта.

На своём опыте скажу, что Xamarin.Forms + System.Reactive + Мобильное устройство = подтормаживания (или тормозище), неоправданный перерасход памяти.


Пару штук observable\observer ваше мобильное приложение выдержит. А вот с десяток, или, как в моём первом проекте с три десятка в одной view (vm), то уже начнутся заметные подтормаживания…
Могу писать о связке rx+xamarin.forms бесконечно долго :)) Но итог один — я крайне не доволен System.Reactive под мобильники.


Если нужна особая асинхронность, то лучше перейти на TPL или поюзать фитчи C#9.0. Меньшее количество задач в багтрекере вам обеспечено! :))


Да и вообще, System.Reactive уже пережил себя с приходом асинхронного программирования. Разве нет?

Всё-таки Reactive UI — это не то же самое, что System.Reactive. Главной целью использования Reactive UI в нашем случае была связка бэкэнд-UI. Используя только асинхронное программирование, вы не сможете без лишних велосипедов оповестить интерфейс об изменениях на бэкэнде. Конечно, вы можете использовать INotifyPropertyChanged, но тут я вынуждена отправить вас перечитать текущую статью, где написано о минусах такого подхода в чистом виде.

Разумеется, использование любого стороннего фреймворка добавляет накладных расходов — тут я спорить не буду. Поэтому и выбирается золотая середина между допустимыми «тормозами» и удобством программирования. В нашем случае Reactive UI нагрузил систему недостаточно, чтобы отказаться от его использования :)
Что-то наподобие интерфейса ICommand и команд в WPF, только интеракции в нашем случае назначались на интерфейсные элементы не декларативно (как с командами в WPF), а программно, что показалось не очень удобным.

Было бы интересно узнать, а почему решили не использовать для подобных штук реактивные команды? ReactiveCommand<TInput, TOutput> — это же реализация ICommand на стероидах, с ThrownExceptions, IsExecuting, etc. Interactions же были задуманы, как один из способов реализации взаимодействий с модальными окнами, и на практике использовать эти штуки обычно доводится нечасто.

Добрый день! Прошу прощения за опоздание с ответом — не сразу увидела Ваш комментарий.
Перед решением не использовать реактивные команды мы не рассматривали этот вариант в принципе (из-за отсутствия опыта использования Reactive UI ранее он просто выпал из области рассмотрения).
Возможно, Ваш вариант с ReactiveCommand был бы более удачным решением (особенно, учитывая описанные недостатки интеракций). Я не имею абсолютно никаких нареканий к ICommand в WPF, и использовать то же самое в Xamarin лично для меня было бы более комфортно

Вообще с командами в ReactiveUI работать несколько более удобно, чем с объектами типа Interaction. Привязывать команду модели представления к элементу интерфейса можно как в XAML-разметке — с помощью синтаксиса {Binding CommandName}, — так и в коде на языках программирования C#, F#, или Visual Basic, с помощью extension-методов ReactiveUI, включая методы Bind, BindCommand, OneWayBind, BindTo. То есть можно делать так:


<Button x:Name="AwesomeButton"
        Content="Hello, world!"
        Command="{Binding AwesomeCommand}" />

Или так:


this.BindCommand(
    ViewModel,
    vm => vm.AwesomeCommand,
    view => view.AwesomeButton);

Последний вариант хорош тем, что при переименовании свойства модели представления, к которой мы привязываем данные, мы узнаем о том, что что-то пошло не так, уже на этапе компиляции приложения. Причём для WPF, Windows Forms и Xamarin Forms это более актуально, чем для UWP или Avalonia, которые поддерживают compiled-биндинги. А на Xamarin.Android или Xamarin.iOS других вариантов в общем-то и нет. Дополнительно, можно подписываться на исключения, выброшенные экземплярами ReactiveCommand, двумя способами — можно подписаться на исключения одной команды:


LoadUsers.ThrownExceptions.Subscribe(
    exception => /* update property etc. */
);

Или на исключения всех команд и OAPH в приложении сразу:


RxApp.DefaultExceptionHandler = Observer.Create(
    error => /* Handle errors. */
);

Такой подход, с одной стороны, позволяет сделать приложение более отказоустойчивым и научить его отправлять отчёты об ошибках куда-нибудь для дальнейшего анализа, а с другой — позволяет не писать try { } catch { } блоки повсеместно в лямбдах, предлагая вместо этого написать реактивный пайплайн наподобие:


_errorMessage = Login // ReactiveCommand<TInput, TOutput>
    .ThrownExceptions // Все исключения свалятся сюда.
    .Select(exception => exception.Message)
    .ToProperty(this, x => x.ErrorMessage);

Впрочем, впоследних версиях ReactiveUI должен быть доступен синтаксис BindInteraction, позволяющий привязывать Interaction к действиям более удобным образом:


// В файле *.xaml.cs:
this.BindInteraction(
    ViewModel,
    vm => vm.MyInteraction,
    context => /* Обработчик взаимодействия. */);
Зарегистрируйтесь на Хабре, чтобы оставить комментарий