如何在 Xamarin.Forms 中设置 ContentPage 方向
How to set ContentPage orientation in Xamarin.Forms
我正在使用 Xamarin.Forms 创建一个跨平台应用程序,我所有的 ContentPages
都位于 PCL
.
我正在寻找一种方法来将单个 ContentPage
的 orientation
设置并锁定为 Landscape
,最好不必在每个 activity 中创建另一个 activity特定于平台的项目。
由于我的 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 查看我可用的不同布局,none 其中有一个 Orientation
属性.
我担心唯一的方法是创建第二个平台特定的 Activity
只为这个平台 ContentPage
并将方向设置为横向。
虽然这种方法可行,但它使屏幕之间的导航变得更加复杂。
目前正在 Android 中进行测试。
不想这么说,但这只能使用 custom renderers 或特定于平台的代码
在android中可以设置MainActivity的RequestedOrientation属性为ScreenOrientation.Landscape
.
在 iOS 中,当 Xamarin.Forms.Application.Current.MainPage
是您感兴趣的ContentPage
。
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;
}
}
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;
}
}
}
这也可以通过使用 MessagingCenter class 将消息从 Form 项目发送到宿主项目来完成。不使用自定义渲染器或依赖服务如下,
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;
});
}
在我的博客中查看更多内容 post : http://www.appliedcodelog.com/2017/05/force-landscape-or-portrait-for-single.html
如果您也 运行 遇到 Android 设备轮换 returns 的问题,您返回提示输入用户电子邮件,您可以跟进 ADAL 和 MSAL 的修复进度这里:
https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/issues/1622 https://github.com/xamarin/xamarin-android/issues/3326
我正在使用 Xamarin.Forms 创建一个跨平台应用程序,我所有的 ContentPages
都位于 PCL
.
我正在寻找一种方法来将单个 ContentPage
的 orientation
设置并锁定为 Landscape
,最好不必在每个 activity 中创建另一个 activity特定于平台的项目。
由于我的 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 查看我可用的不同布局,none 其中有一个 Orientation
属性.
我担心唯一的方法是创建第二个平台特定的 Activity
只为这个平台 ContentPage
并将方向设置为横向。
虽然这种方法可行,但它使屏幕之间的导航变得更加复杂。
目前正在 Android 中进行测试。
不想这么说,但这只能使用 custom renderers 或特定于平台的代码
在android中可以设置MainActivity的RequestedOrientation属性为ScreenOrientation.Landscape
.
在 iOS 中,当 Xamarin.Forms.Application.Current.MainPage
是您感兴趣的ContentPage
。
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;
}
}
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;
}
}
}
这也可以通过使用 MessagingCenter class 将消息从 Form 项目发送到宿主项目来完成。不使用自定义渲染器或依赖服务如下,
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;
});
}
在我的博客中查看更多内容 post : http://www.appliedcodelog.com/2017/05/force-landscape-or-portrait-for-single.html
如果您也 运行 遇到 Android 设备轮换 returns 的问题,您返回提示输入用户电子邮件,您可以跟进 ADAL 和 MSAL 的修复进度这里:
https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/issues/1622 https://github.com/xamarin/xamarin-android/issues/3326