company_banner

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



    Друзья! Очередная статья на тему разработки мобильных приложений на 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 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, который из коробки позволяет использовать большое количество иконок.





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



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



    • Assets\Fonts для Android
    • Resources\Fonts для 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, которые позволяют упростить и ускорить создание бизнес-приложений.



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



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



    Об авторах



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

    Другие статьи автора:


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


    Microsoft

    298,12

    Microsoft — мировой лидер в области ПО и ИТ-услуг

    Поделиться публикацией
    Комментарии 15
      +1
      Вместо NCanvas рекомендую посмотреть в сторону SkiaSharp. Там куда более богатый набор возможностей.
        0
        Спасибо! SkiaSharp штука хорошая, но это все-таки больше полноценная платформа для рисования графики. А вот NControl подходит для разных мелочей, которые быстрее нарисовать руками, чем возиться с подгонкой графики под разные экраны.
          0

          А у вас SkiaSharp в UWP сейчас работает?

            0
            Мы его для UWP не пробовали. Возможно, кто-нибудь из хабравцев сможет ответить :)
          0
          Всегда читаю ваши статьи по Xamarin.Forms с удовольствием! Так как вижу в Мобильных Приложениях тренд, а с этой платформой (ее бесплатностью, спасибо Microsoft) где «делаешь в одном» месте, а работает на трех — появляется желание разбираться в мобильных разработках езе больше.
            0
            Я тоже читаю про Xamarin.Forms с удовольствием. Но чаще на stackoverflow.com и developer.xamarin.com — потому что пишу на нём коммерческие приложения. И вот я не очень согласный с «делаешь в одном месте, а работает на трёх». Хоть и считаю что для коммерческой кросс-платформенной нативной разработки для Xamarin альтернатив нет, и он мне весьма сам по себе концептуально нравится.

            А вот даже упомянутые бизнес-приложения полностью, без кастомизации (тех же рендереров) под платформы не сделать. Где вы видели «бизнес-приложения» без чекбоксов? А их в формах нет. Хорошо хоть карусель добавили (и та пока бета).

            Какие-то задачи решал XLabs, но сейчас facing and struggling in dependency hell. Обратная сторона xamarin — версии пакетов даже из коробки не всегда в чистом проекте собирались.

            Вобщем это не так что надо знать только С# и Xamarin. Надо знать еще кучку-другую глубокоподводных камешков :) При всей любви и всем уважении.
              0
              «бизнес-приложения» без чекбоксов?

              на iOS.
                0
                Ии? Вы на iOS не видели приложений где они есть (пусть даже не особо нативные)? Или что это такое show-stop-оправдание для Xamarin.Forms, что Switch решает все проблемы? Или может быть хотите сказать что интерфейс это в 95% случаев совсем не 95% приложения, пусть оно хоть совсем будет «бизнес-»? Или что дизайнеры не хотят чекбоксы, а хотят нативные Switch? Или что вы в курсе (а я типа нет), что на iOS всё не так, как на Андроиде? Или что вы вырвав цитатой мелкий кусок моего сообщения обесценили его вконец? Что Xamarin.Forms Checkbox-то и не нужен вовсе, раз у Apple все не так? А вы один на Xamarin пишете и на Forms под все платформы сразу без Custom Renderer'ов?

                Чо надо-то??
                  0
                  Вы спросили, я ответил.
                  В XF до недавнего времени не было ScrollView которое может в две стороны скролиться, из-за того что в Android его нет.

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

                  Если у вас такой дизайн, что вам позарез нужен именно чекбокс, то велика вероятность, что чекбокс нарисованный Xamarin`овскими дизайнерами вам тупо не подойдёт и вам все равно придётся использовать кастомный рендерер.

                  И после всего вышесказанного возникает вопрос, а насколько действительно необходим чекбокс платформе? Наверное неплохо было бы, но не в первом приоритете. Есть проблемы поважнее.

                  Ну и ещё одно обстоятельство, что конктретно для этого случая можно просто запилить нативные контролы используя Native Embedding, а не кастомные рендеры.

                  И да, я прекрасно понимаю, что без знания особенностей целевых платформ ты ничего толком не напишешь. Но это даже на PhoneGap так.
                    0
                    Это был риторический вопрос.
            0
            Удалось реализовать возможность добавления svg-иконки в шрифт в пользовательском режиме?
            Больше работаю с UWP, но задача одна.
              0
              Про пользовательский режим не совсем понятно. На базе SVG-иконок создается TTF-шрифт, который по аналогии с обычными шрифтами используется в приложении.
                0
                В таком режиме я и использую.
                Есть потребность встроить в приложение генерацию своего шрифта. К примеру, в приложении уже есть свой шрифт. Иконки со шрифта используются как часть данных. Нужна возможность чтобы пользователь выбрал svg-картинку, далее програмно в существующий шрифт была добавлена эта картинка или сгенерирован новый шрифт заменяющий текущий. Вот так у меня не получается сделать.
                  0
                  А вам не проще сразу рисовать картинку, не пересоздавая шрифты? Вот так, напрмер?
                    0
                    Да, так будет проще, попробую.
                    В этом варианте останется реализовать адаптацию картинки под переключение фона, как в шрифтах. Фон светлый — символ темный и наоборот. Спасибо!

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое