Как справиться с поворотом / ориентацией экрана в формах Xamarin?

Существует ли (наполовину) общий способ обработки поворота / ориентации в формах Xamarin для различных видов и платформ (Android, iOS, WinPhone)?

Пользовательский интерфейс вращается, и это достаточно хорошо, хотя это наносит ущерб моему макету (абсолютный макет прямо сейчас). Я полагаю, с помощью Stacklayout я мог бы сделать его немного более гибким, но затем столкнулся бы с блокпостом где-нибудь еще, когда макет более сложный.

Можно ли как-то отображать разные виды для портрета и ландшафта с помощью одной и той же ViewModel? (Я использую MVBM на основе XLAB.)

Возможные решения, которые я нашел:

http://blog.rthand.com/post/2014/07/24/Different-XAML-layouts-for-different-device-orienations-in-XamarinForms.aspx не хватает iOS, и мне интересно, будет ли он работать с MVVM слишком хорошо, кажется, хорошо, и я сейчас расследую это

http://www.jimbobbennett.io/orientation-with-xamarin-forms/ звучит многообещающе, но образец только для iOS, связанный репозиторий GIT вообще не имеет документации, он просто говорит "Помощники Xamarin"

http://www.sellsbrothers.com/posts/Details/13740 также может быть возможностью для программно созданных видов. Хотя в моих тестах я не получил событие изменения размера (хотя я слушал в другом месте кода) для симулятора ios при вращении. (Решение основано на изменении размера для обнаружения вращения.)

1 ответ

Решение

Если вы уже используете XLabs, вы можете использовать IXFormsApp и свойство Orientation и обработчик событий Rotation. Вам придется добавить нативных наблюдателей для каждой платформы и установить там "Ориентацию" IXFormsApp, которая вызовет обработчик события.

Например на iOS:

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        var xapp = new XFormsAppiOS();
        xapp.Init(this);

        var resolverContainer = new SimpleContainer();
        resolverContainer.Register<IXFormsApp>(xapp);
        Resolver.SetResolver(resolverContainer.GetResolver());

        var a = new App();
        LoadApplication(a);

        UIDevice.Notifications.ObserveOrientationDidChange((s, e) =>
        {
            xapp.Orientation = ... // set orientation here
        });

Теперь вы можете отслеживать изменения ориентации, разрешив IXFormsApp:

        xapp = Resolver.Resolve<IXFormsApp>();
        if (xapp.Orientation == Orientation.Landscape) { ... } else { ... } 
        xapp.Rotation += (sender, args) =>
        {
            switch (args.Value)
            {
                case Orientation.LandscapeLeft:
                    break;
                default:
                    // etc.
                    break;
            }
        };

Что касается макетов, я бы предположил, что RelativeLayout будет наиболее удобным выбором, так как вы можете поместить ориентацию внутри ограничения. При повороте заставьте макет обновиться сам.

Другие вопросы по тегам