簡體   English   中英

如何在Xamarin.Forms中設置ContentPage方向

[英]How to set ContentPage orientation in Xamarin.Forms

我正在使用Xamarin.Forms來創建跨平台應用程序,我的所有ContentPages都位於PCL

我正在尋找一種方法來設置和鎖定單個ContentPageLandscapeorientation ,最好不必在每個特定於平台的項目中創建另一個活動。

由於我的ContentPage.Content設置為ScrollView ,我嘗試將ScrollOrientation設置為Horizontal ,但這不起作用。

我也嘗試過使用RelativeLayout ,但我在這上面看不到Orientation屬性。

public class PlanningBoardView : ContentPage //Container Class.
    {
        public PlanningBoardView()
        {
            scroller = new ScrollView ();

            Board = new PlanningBoard();

            scroller.Orientation = ScrollOrientation.Horizontal;
            scroller.WidthRequest = Board.BoardWidth;
            scroller.Content = Board;

            Content = scroller;
        }
    }

我嘗試的最后一件事是使用Xamarin Studio的Intellisense版本和Xamarin Forms API Doc來查看我可用的不同布局,其中沒有一個具有Orientation屬性。

我擔心唯一的方法是為這個ContentPage創建第二個特定於平台的Activity ,並將方向設置為landscape。

雖然這種方法可行,但它使屏幕之間的導航變得更加復雜。

目前正在Android中測試。

討厭這樣說,但這只能使用自定義渲染器或特定於平台的代碼來完成

在android中,您可以將MainActivity的RequestedOrientation屬性設置為ScreenOrientation.Landscape

在iOS中,您可以覆蓋GetSupportedInterfaceOrientationsAppDelegate類返回的一個UIInterfaceOrientationMask值時, Xamarin.Forms.Application.Current.MainPageContentPage你是在intereted。



Android的

[assembly: Xamarin.Forms.ExportRenderer(typeof(MyCustomContentPage), typeof(CustomContentPageRenderer))]

public class CustomContentPageRenderer : Xamarin.Forms.Platform.Android.PageRenderer
{
    private ScreenOrientation _previousOrientation = ScreenOrientation.Unspecified;

    protected override void OnWindowVisibilityChanged(ViewStates visibility)
    {
        base.OnWindowVisibilityChanged(visibility);

        var activity = (Activity)Context;

        if (visibility == ViewStates.Gone)
        {
            // Revert to previous orientation
            activity.RequestedOrientation = _previousOrientation == ScreenOrientation.Unspecified ? ScreenOrientation.Portrait : _previousOrientation;
        }
        else if (visibility == ViewStates.Visible)
        {
            if (_previousOrientation == ScreenOrientation.Unspecified)
            {
                _previousOrientation = activity.RequestedOrientation;
            }

            activity.RequestedOrientation = ScreenOrientation.Landscape;
        }
    }
}

iOS版

public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
    {
        if (Xamarin.Forms.Application.Current == null || Xamarin.Forms.Application.Current.MainPage == null)
        {
            return UIInterfaceOrientationMask.Portrait;
        }

        var mainPage = Xamarin.Forms.Application.Current.MainPage;

        if (mainPage is MyCustomContentPage ||
           (mainPage is NavigationPage && ((NavigationPage)mainPage).CurrentPage is MyCustomContentPage) ||
           (mainPage.Navigation != null && mainPage.Navigation.ModalStack.LastOrDefault() is MyCustomContentPage))
        {
            return UIInterfaceOrientationMask.Landscape;
        }

        return UIInterfaceOrientationMask.Portrait;
    }
}

這也可以通過使用MessagingCenter類將表單項目中的消息發送到主機項目來完成。 不使用自定義渲染器或依賴服務,如下所示,

public partial class ThirdPage : ContentPage
  {
      protected override void OnAppearing()
      { 
          base.OnAppearing(); 
         MessagingCenter.Send(this, "allowLandScapePortrait");
      }
       //during page close setting back to portrait
      protected override void OnDisappearing()
      {
          base.OnDisappearing(); 
          MessagingCenter.Send(this, "preventLandScape");
      }
  }

更改mainactivity以接收消息並設置RequestedOrientation

[Activity(Label = "Main", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,ScreenOrientation = ScreenOrientation.Portrait)]
 public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
  {        
  //allowing the device to change the screen orientation based on the rotation
  MessagingCenter.Subscribe<ThirdPage>(this, "allowLandScapePortrait", sender =>
  { 
   RequestedOrientation = ScreenOrientation.Unspecified;
  });
 //during page close setting back to portrait
 MessagingCenter.Subscribe<ThirdPage>(this, "preventLandScape", sender =>
  { 
   RequestedOrientation = ScreenOrientation.Portrait;
  });
 }

在我的博客文章中查看更多內容: http//www.appliedcodelog.com/2017/05/force-landscape-or-portrait-for-single.html

如果您在Android上遇到問題,設備輪換會將您返回到提示用戶電子郵件,則可以在此處跟進ADAL和MSAL的修復進度:

https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/issues/1622 https://github.com/xamarin/xamarin-android/issues/3326

Dealdiane的代碼對我來說效果很好,但有一點變化:

protected override void OnWindowVisibilityChanged(ViewStates visibility) {
    base.OnWindowVisibilityChanged( visibility );

    IRotationLock page = Element as IRotationLock;
    if ( page == null )
        return;

    var activity = (Activity) Context;

    if ( visibility == ViewStates.Gone ) {
        // Revert to previous orientation
        activity.RequestedOrientation = _previousOrientation;
    } else if ( visibility == ViewStates.Visible ) {
        if ( _previousOrientation == ScreenOrientation.Unspecified ) {
            _previousOrientation = activity.RequestedOrientation;
        }

        switch ( page.AllowRotation() ) {
            case RotationLock.Landscape:
                activity.RequestedOrientation = ScreenOrientation.SensorLandscape;
                break;
            case RotationLock.Portrait:
                activity.RequestedOrientation = ScreenOrientation.SensorPortrait;
                break;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM