Проверка ориентации устройстваChecking Device Orientation

Скачать пример Скачать примерDownload Sample Download the sample

В этой статье приводятся инструкции по использованию DependencyService для проверки ориентации устройства из общего кода с помощью собственных интерфейсов API на каждой платформе.This article will guide you to use DependencyService to check the device orientation from shared code using the native APIs on each platform. Это пошаговое руководство основано на подключаемом модуле DeviceOrientation, разработанном Али Озгюром (Ali Özgür).This walkthrough is based on the existing DeviceOrientation plugin by Ali Özgür. Дополнительные сведения см. в репозитории GitHub.See the GitHub repo for more information.

У приложения, использующего DependencyService, будет следующая структура:The application using DependencyService will have the following structure:

Примечание

Определить, имеет ли устройство книжную или альбомную ориентацию, можно с помощью метода, описанного в статье Ориентация устройства.It is possible to detect whether the device is in portrait or landscape orientation in shared code, as demonstrated in Device Orientation. Метод, рассматриваемый в этой статье, предполагает использование собственных функций для получения дополнительных сведений об ориентации, в том числе о том, перевернуто ли устройство.The method described in this article uses native features to get more information about orientation, including whether the device is upside down.

Создание интерфейсаCreating the Interface

Сначала создайте в общем коде интерфейс для функциональности, которую вы планируете реализовать.First, create an interface in the shared code that expresses the functionality you plan to implement. В этом примере интерфейс содержит один метод:For this example, the interface contains a single method:

namespace DependencyServiceSample.Abstractions
{
    public enum DeviceOrientations
    {
        Undefined,
        Landscape,
        Portrait
    }

    public interface IDeviceOrientation
    {
        DeviceOrientations GetOrientation();
    }
}

Реализация этого интерфейса в общем коде позволит приложению Xamarin.Forms обращаться к интерфейсам API ориентации устройства на каждой платформе.Coding against this interface in the shared code will allow the Xamarin.Forms app to access the device orientation APIs on each platform.

Примечание

Для работы с DependencyService классы, реализующие интерфейс, должны иметь конструктор без параметров.Classes implementing the interface must have a parameterless constructor to work with the DependencyService.

Реализация в iOSiOS Implementation

Интерфейс необходимо реализовать в проекте приложения для каждой платформы.The Interface must be implemented in each platform-specific application project. Обратите внимание на то, что класс имеет конструктор без параметров. Это позволяет DependencyService создавать экземпляры.Note that the class has a parameterless constructor so that the DependencyService can create new instances:

using UIKit;
using Foundation;

namespace DependencyServiceSample.iOS
{
    public class DeviceOrientationImplementation : IDeviceOrientation
    {
        public DeviceOrientationImplementation(){ }

        public DeviceOrientations GetOrientation()
        {
            var currentOrientation = UIApplication.SharedApplication.StatusBarOrientation;
            bool isPortrait = currentOrientation == UIInterfaceOrientation.Portrait
                || currentOrientation == UIInterfaceOrientation.PortraitUpsideDown;

            return isPortrait ? DeviceOrientations.Portrait: DeviceOrientations.Landscape;
        }
    }
}

Наконец, добавьте следующий атрибут [assembly] над классом (и вне всех определенных пространств имен), включая все обязательные операторы using:Finally, add this [assembly] attribute above the class (and outside any namespaces that have been defined), including any required using statements:

using UIKit;
using Foundation;
using DependencyServiceSample.iOS; //enables registration outside of namespace

[assembly: Xamarin.Forms.Dependency (typeof (DeviceOrientationImplementation))]
namespace DependencyServiceSample.iOS {
    ...

Атрибут регистрирует класс как реализацию интерфейса IDeviceOrientation. Это означает, что для создания его экземпляра можно использовать метод DependencyService.Get<IDeviceOrientation> в общем коде.This attribute registers the class as an implementation of the IDeviceOrientation Interface, which means that DependencyService.Get<IDeviceOrientation> can be used in the shared code to create an instance of it.

Реализация в AndroidAndroid Implementation

В следующем коде реализуется интерфейс IDeviceOrientation в Android.The following code implements IDeviceOrientation on Android:

using DependencyServiceSample.Droid;
using Android.Hardware;

namespace DependencyServiceSample.Droid
{
    public class DeviceOrientationImplementation : IDeviceOrientation
    {
        public DeviceOrientationImplementation() { }

        public static void Init() { }

        public DeviceOrientations GetOrientation()
        {
            IWindowManager windowManager = Android.App.Application.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();

            var rotation = windowManager.DefaultDisplay.Rotation;
            bool isLandscape = rotation == SurfaceOrientation.Rotation90 || rotation == SurfaceOrientation.Rotation270;
            return isLandscape ? DeviceOrientations.Landscape : DeviceOrientations.Portrait;
        }
    }
}

Добавьте следующий атрибут [assembly] над классом (и вне всех определенных пространств имен), включая все обязательные операторы using.Add this [assembly] attribute above the class (and outside any namespaces that have been defined), including any required using statements:

using DependencyServiceSample.Droid; //enables registration outside of namespace
using Android.Hardware;

[assembly: Xamarin.Forms.Dependency (typeof (DeviceOrientationImplementation))]
namespace DependencyServiceSample.Droid {
    ...

Этот атрибут регистрирует класс как реализацию интерфейса IDeviceOrientaiton. Это означает, что для создания его экземпляра можно использовать метод DependencyService.Get<IDeviceOrientation> в общем коде.This attribute registers the class as an implementation of the IDeviceOrientaiton Interface, which means that DependencyService.Get<IDeviceOrientation> can be used in the shared code can create an instance of it.

Реализация на универсальной платформе WindowsUniversal Windows Platform Implementation

В следующем коде реализуется интерфейс IDeviceOrientation на универсальной платформе Windows.The following code implements the IDeviceOrientation interface on the Universal Windows Platform:

namespace DependencyServiceSample.WindowsPhone
{
    public class DeviceOrientationImplementation : IDeviceOrientation
    {
        public DeviceOrientationImplementation() { }

        public DeviceOrientations GetOrientation()
        {
            var orientation = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().Orientation;
            if (orientation == Windows.UI.ViewManagement.ApplicationViewOrientation.Landscape) {
                return DeviceOrientations.Landscape;
            }
            else {
                return DeviceOrientations.Portrait;
            }
        }
    }
}

Добавьте атрибут [assembly] над классом (и вне всех определенных пространств имен), включая все обязательные операторы using:Add the [assembly] attribute above the class (and outside any namespaces that have been defined), including any required using statements:

using DependencyServiceSample.WindowsPhone; //enables registration outside of namespace

[assembly: Dependency(typeof(DeviceOrientationImplementation))]
namespace DependencyServiceSample.WindowsPhone {
    ...

Этот атрибут регистрирует класс как реализацию интерфейса DeviceOrientationImplementation. Это означает, что для создания его экземпляра можно использовать метод DependencyService.Get<IDeviceOrientation> в общем коде.This attribute registers the class as an implementation of the DeviceOrientationImplementation Interface, which means that DependencyService.Get<IDeviceOrientation> can be used in the shared code can create an instance of it.

Реализация в общем кодеImplementing in Shared Code

Теперь можно написать и протестировать общий код, который обращается к интерфейсу IDeviceOrientation.Now we can write and test shared code that accesses the IDeviceOrientation interface. На этой простой странице есть кнопка, текст которой изменяется в зависимости от ориентации устройства.This simple page includes a button that updates its own text based on the device orientation. Для получения экземпляра IDeviceOrientation интерфейса – используется DependencyService. Во время выполнения этот экземпляр будет представлять собой зависящую от платформы реализацию с полным доступом к собственному пакету SDK.It uses the DependencyService to get an instance of the IDeviceOrientation interface – at runtime this instance will be the platform-specific implementation that has full access to the native SDK:

public MainPage ()
{
    var orient = new Button {
        Text = "Get Orientation",
        VerticalOptions = LayoutOptions.CenterAndExpand,
        HorizontalOptions = LayoutOptions.CenterAndExpand,
    };
    orient.Clicked += (sender, e) => {
       var orientation = DependencyService.Get<IDeviceOrientation>().GetOrientation();
       switch(orientation){
           case DeviceOrientations.Undefined:
                orient.Text = "Undefined";
                break;
           case DeviceOrientations.Landscape:
                orient.Text = "Landscape";
                break;
           case DeviceOrientations.Portrait:
                orient.Text = "Portrait";
                break;
       }
    };
    Content = orient;
}

Если запустить это приложение в iOS, Android или Windows и нажать кнопку, ее текст обновится в соответствии с ориентацией устройства.Running this application on iOS, Android, or the Windows platforms and pressing the button will result in the button's text updating with the device's orientation.