Повышаем эффективность работы в Xamarin.Forms

в 6:50, , рубрики: .net, C#, Mono и Moonlight, xamarin, xamarin.forms, xamarincolumn, Блог компании Microsoft, мобильные приложения, разработка мобильных приложений

Повышаем эффективность работы в Xamarin.Forms - 1

Друзья! Очередная статья на тему разработки мобильных приложений на Xamarin. Мы не прекращаем рассмотривать особенности использования Xamarin.Forms при разработке бизнес-приложений для iOS и Android. Все статьи из колонки можно найти и прочитать по ссылке #xamarincolumn

В прошлой статье мы рассмотрели, как можно повысить продуктивность при разработке мобильных приложений с использованием Xamarin, а также отметили базовые механизмы повышения производительности бизнес-приложений на базе Xamarin.Forms.

В сегодняшнем материале мы продолжим выбранный курс и расскажем об использовании Fody для сокращения необходимого программного кода, а также узнаем об использовании иконочных шрифтов и библиотеки NControlView для ручной отрисовки интерфейсных элементов.

Что такое бизнес-приложения?

Для того, чтобы мы с вами находились на одной странице и использовали одинаковые понятия, давайте для начала определимся с тем, чем же бизнес-приложения отличаются от игр и других типов программ.

Мобильные приложения, как и любые другие программные продукты, создаются для определенных целей, исходя из которых уже и можно определиться с выбором подходящего инструментария для разработки.

Для простоты, мы разделяем типы мобильных приложений по следующим критериям:

  • Сложность интерфейса (UI) — наличие и использование своих анимаций и спец. эффектов, своя концепция пользовательского интерфейс.
  • Использование возможностей ОС — оптимизация под различное железо, использование системных механизмов.
  • Частота использования — как часто пользователь будет запускать приложение.

На основе данных критериев мы условно (всегда есть исключения!) разделяем все приложения на следующие основные сегменты:

  • игры (высокая сложность UI, высокое использование функциональности ОС, частое использование),
  • развлечения/мультимедиа (средняя сложноcть UI, высокое использование функциональности ОС, частое использование),
  • бизнес-приложения (средняя и низкая сложность UI, невысокое использование возможностей ОС, средняя и низкая частота использования),
  • общение (средняя и низкая сложность UI, невысокое использование возможностей ОС, высокая частота использования).

В прошлом нам доводилось участвовать в создании всех перечисленных видов приложений, поэтому знаем особенности разработки каждого из них. Если рассматривать игры, то здесь мы бы рекомендовали использовать Unity3D или аналогичный зрелый фреймворк. Для мультимедиа и общения лучше выбрать классические Xamarin.iOS и Xamarin.Android. А вот для бизнес-приложений отлично подходит Xamarin.Forms, особенно с учетом сокращения трудозатрат на разработку и сопровождение в среднем на 60% относительно создания отдельных версий на iOS и Android.

Итак, с тем, что такое бизнес-приложения мы определились.

Сокращаем объем кода с помощью Fody

Одна из причин, по которой мы пришли к Xamarin, а затем и к Xamarin.Forms для разработки бизнес-приложений, это высокая продуктивность разработки (“тот же результат при меньших трудозатратах”). Поэтому сегодня мы хотим рассказать о небольшом твике, который позволяет заметно сократить объем кода при описании ViewModel. В этом нам поможет замечательный инструмент Fody (полезная статья на Хабре).

Напомним, что для реализации паттерна MVVM и биндинга свойств, ViewModel должна вызывать событие PropertyChanged, после которого и происходит фактическая передача данных для отображения во View.

Классический подход подразумевает создание private-переменных и ручной вызов PropertyChanged, что ведет к созданию довольно объемных ViewModel:

    using System.Runtime.CompilerServices;
    using System.ComponentModel;

    public class LoginViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _login;
        public string Login {
            get { 
                return _login; 
                  }
          set {
                if (value != _login) {
                    _login = value;
                    NotifyPropertyChanged ();
                }
            }
        }

        private string _password;
        public string Password {
            get { 
                return _password; 
            }
            set {
                if (value != _password) {
                    _password = value;
                    NotifyPropertyChanged ();
                }
            }
        }

        private void NotifyPropertyChanged ([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null) {
                PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
            }
        }
    }

Объемно, не так ли?

А вот, как будет выглядеть та же самая ViewModel при использовании плагина PropertyChanged.Fody:

    using PropertyChanged;

    [ImplementPropertyChanged]
    public class LoginViewModel
    {
        public string Login { get; set; }
        public string Password { get; set; }
    }

Заметное сокращение рутины :) Для этого необходимо просто добавить данный плагин через Nuget.

Повышаем эффективность работы в Xamarin.Forms - 2

В Xamarin Studio может потребоваться вручную задать у файла FodyWeavers.xml свойства Build Action -> Content, и Quick Properties -> Copy to Output Directory, плюс внести информацию о плагине в файл FodyWeavers.xml:

<?xml version="1.0" encoding="utf-8" ?>  
<Weavers>  
    <PropertyChanged />
</Weavers>  

В нашей практике мы также используем следующие плагины Fody (другие пока не прижились):

Иконочные шрифты

В современной практике мобильной разработки приходится работать с большим количеством разрешений экранов, поэтому раньше в приложении приходилось иметь большое количество изображений разного размера, чтобы иконки отображались корректно, без артефактов и лишнего использования памяти. Несколько лет назад в мире веб-разработки стали активно использоваться иконочные шрифты Font Awesome, которые позволяли уйти от большого количества изображений и гибко адаптировать верстку под различные разрешения и плотность дисплеев. Со временем данный подход перекочевал и в сферу мобильной разработки.

Сейчас существует большое количество бесплатных и открытых иконочных шрифтов, однако наиболее целесообразным будет создание своих иконочных шрифтов, содержащих нужные наборы изображений для каждой платформы.

Начнем мы с создания иконочного шрифта. Для этого нам понадобятся изображения в формате SVG и бесплатный сервис Glyphter, который из коробки позволяет использовать большое количество иконок.

Повышаем эффективность работы в Xamarin.Forms - 3

Сами иконки мы рекомендуем создавать в стилистике целевой платформы или использовать готовые наборы (например, icons8).

Далее нам необходимо эти шрифты скачать в формате TTF и поместить в корректные папки:

  • AssetsFonts для Android
  • ResourcesFonts для iOS (плюс их надо прописать в Info.plist)

Для того, чтобы их использовать иконочный шрифт потребуется создать свой простой наследник Label с рендерарами для каждой платформы. Подробнее — в документации Xamarin.
И, наконец, для тех, кому будет достаточно готовых шрифтов (уже есть все рендереры и добавлены нужные ресурсы), могут использовать готовую библиотеку Iconize для Xamarin.Forms (доступны сборки в Nuget).

Рисуем с помощью NControl

Иногда, хотя и не так часто, при разработке приложений возникает необходимость реализовать ручную отрисовку какого-либо интерфейсного элемента. Да, можно вместо него использовать готовые изображений (для всех разрешений, с сохранением пропорций и прочие мелкие сложно) или использовать 9-patch SVG. Однако часто можно обойтись простой ручной отрисовкой нужного элемента. Для этих целей и был создан компонент NControl. Если коротко, то это механизм виртуализации отрисовки поверх стандартных механизмов iOS, Android и Windows.

Для начала (как и многие другие кастомные контролы и библиотеки) необходимо инициализировать компонент: добавить строку NControlViewRenderer.Init() после Forms.Init() в классах AppDelegate для iOS и MainActivity для Android.

Далее можно напрямую добавить нужный компонент в коде на C#:

  var myView = new NControlView {
      DrawingFunction = (canvas, rect) => {
          canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);
          canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);
      }
  };

Но на наш взгляд лучше создать своего наследника от NControlView и использовать его в Xaml:

public class MyControl: NControlView
{
  public override void Draw(NGraphics.ICanvas canvas, NGraphics.Rect rect)
  {
    canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);
    canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);
  }
}

Еще NControl можно использовать для создания различных анимаций пользовательского интерфейса — пример реализации открытия диалога в духе Skype.

Больше примеров мы можете на странице описания компонента: github.com/chrfalch/NControl

Заключение

Итак, сегодня мы определили класс приложений, для которых хорошо подходит Xamarin.Forms, познакомились с Fody, иконочными шрифтами и библиотекой NControl, которые позволяют упростить и ускорить создание бизнес-приложений.

В следующей статье мы более детально рассмотрим работу с экранами и состояниями, а также небольшие твики для придания приложениям законченного вида.

Оставайтесь на связи и добавляйте свои комментарии и вопросы!

Об авторах

Повышаем эффективность работы в Xamarin.Forms - 4
Вячеслав Черников — руководитель отдела разработки компании Binwell. В прошлом — один из Nokia Champion и Qt Certified Specialist, в настоящее время — специалист по платформам Xamarin и Azure. В сферу mobile пришел в 2005 году, с 2008 года занимается разработкой мобильных приложений: начинал с Symbian, Maemo, Meego, Windows Mobile, потом перешел на iOS, Android и Windows Phone.

Полезные ссылки

Автор: Microsoft

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js