简体   繁体   中英

Xamarin.Forms - change device orientation based on device resolution

is there any chance to force change screen orientation based device screen resolution?

Have app for tablets, but I want to run app on mobile device too. I have a few pages, where I need to change orientation to landscape on phone, because then is my listview a litle bit messy.

Thank you for any advice and I apologize for the bad English:)

You can use MessagingCenter to achieve that.

For example, when navigating from MainPage to PageTwo in Forms, the content page of PageTwo as follow:

public partial class PageTwo : ContentPage
{
    public PageTwo()
    {
        InitializeComponent();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        MessagingCenter.Send(this, "allowLandScape");
    }
    //during page close setting back to portrait
    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        MessagingCenter.Send(this, "quitLandScape");
    }
}

In Android , need to modify MainActivity as follow:

[Activity(Label = "ForceOrientation", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    //allowing the device to change the screen orientation based on the rotation

    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());

        MessagingCenter.Subscribe<PageTwo>(this, "allowLandScape", sender =>
        {
            RequestedOrientation = ScreenOrientation.Landscape;
        });

        //during page close setting back to portrait
        MessagingCenter.Subscribe<PageTwo>(this, "quitLandScape", sender =>
        {
            RequestedOrientation = ScreenOrientation.Portrait;
        });
    }
}

In iOS , we need to create a PageTwoRenderer as follow:

[assembly: ExportRenderer(typeof(PageTwo), typeof(PageTwoRenderer))]
namespace ForceOrientation.iOS
{
    public class PageTwoRenderer : PageRenderer
    {

        public PageTwoRenderer()
        {
            MessagingCenter.Subscribe<PageTwo>(this, "allowLandScape", sender =>
            {
                UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)(UIInterfaceOrientation.LandscapeLeft)), new NSString("orientation"));
            });

            //during page close setting back to portrait
            MessagingCenter.Subscribe<PageTwo>(this, "quitLandScape", sender =>
            {
                UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)(UIInterfaceOrientation.Portrait)), new NSString("orientation"));
            });
        }
      
    }
}

==============================Update=============================

We can use Xamarin.Essentials: Device Information to check whether the device is Phone , Tablet or other devices .

DeviceInfo.Idiom correlates a constant string that maps to the type of device the application is running on. The values can be checked with the DeviceIdiom struct:

  • DeviceIdiom.Phone – Phone
  • DeviceIdiom.Tablet – Tablet
  • DeviceIdiom.Desktop – Desktop
  • DeviceIdiom.TV – TV
  • DeviceIdiom.Watch – Watch
  • DeviceIdiom.Unknown – Unknown

Modiied PageTwo as follow:

protected override void OnAppearing()
{
    base.OnAppearing();

    var idiom = DeviceInfo.Idiom;

    if (idiom == DeviceIdiom.Phone)
    {
        MessagingCenter.Send(this, "allowLandScape");
    }
       
}
//during page close setting back to portrait
protected override void OnDisappearing()
{
    base.OnDisappearing();
    var idiom = DeviceInfo.Idiom;

    if (idiom == DeviceIdiom.Phone)
    {
        MessagingCenter.Send(this, "quitLandScape");
    }
       
}

You can force set orientation on these few pages

// on IOS -> AppDelegate.cs

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
{
    if (Device.Idiom == TargetIdiom.Phone ) {
    {
        return UIInterfaceOrientationMask.Landscape;
    }
    else
    {
        return UIInterfaceOrientationMask.Portrait;
    }
}

// and on Android -> MainActivity.cs do the same if else in here

protected override void OnCreate(Bundle savedInstanceState)       
{
    if (Device.Idiom == TargetIdiom.Phone)
    {
        RequestedOrientation = ScreenOrientation.Landscape; 
    }
    else
    {
        RequestedOrientation = ScreenOrientation.Portrait;
    }

}

You can check about Device class more in documentation https://docs.microsoft.com/en-us/xamarin/xamarin-forms/platform/device#deviceidiom

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM