【问题标题】:How to set ContentPage orientation in Xamarin.Forms如何在 Xamarin.Forms 中设置 ContentPage 方向
【发布时间】:2015-08-22 15:05:52
【问题描述】:

我正在使用 Xamarin.Forms 创建一个跨平台应用程序,我所有的 ContentPages 都位于 PCL 内。

我正在寻找一种方法来设置和锁定单个ContentPageorientationLandscape,最好不必在每个平台特定项目中创建另一个活动。

由于我的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's 查看可供我使用的不同布局,其中没有一个具有 Orientation 属性。

我担心这样做的唯一方法是为这个ContentPage 创建第二个特定于平台的Activity 并将方向设置为横向。

虽然这种方法可行,但它使屏幕之间的导航更加复杂。

目前正在 Android 中进行测试。

【问题讨论】:

    标签: android android-activity xamarin xamarin.forms


    【解决方案1】:

    不想这么说,但这只能使用custom renderers 或特定于平台的代码来完成

    在android中,可以将MainActivity的RequestedOrientation属性设置为ScreenOrientation.Landscape

    在 iOS 中,当 Xamarin.Forms.Application.Current.MainPage 是您感兴趣的 ContentPage 时,您可以覆盖 AppDelegate 类中的 GetSupportedInterfaceOrientations 以返回 UIInterfaceOrientationMask 值之一。



    安卓

    [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;
        }
    }
    

    【讨论】:

    • 有没有机会举个例子? (Android 会做。)
    • 当然。我编辑了我的答案。该示例将强制使用横向模式,但您可以根据需要对其进行更改。
    • 我已经实现了iOS版本,但它不会自动旋转......这可能吗?
    • 自动旋转是什么意思?你的意思是强制某个方向?当然有可能。这就是代码的全部意义所在。也许如果你能提供一个 mcve(或者创建另一个问题?),更多的人可以为你提供指导..
    【解决方案2】:

    这也可以通过使用 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

    【讨论】:

      【解决方案3】:

      如果您在 Android 上也遇到问题,设备轮换返回提示用户电子邮件,您可以在此处跟进 ADAL 和 MSAL 的修复进度:

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

      【讨论】:

        【解决方案4】:

        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;
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-16
          • 2017-03-04
          • 2018-08-20
          • 2019-03-30
          • 2021-12-04
          • 2020-01-26
          • 2014-08-30
          • 2016-01-22
          相关资源
          最近更新 更多