在 Xamarin Forms 中控制单页方向和视图旋转
Control single page orientation and view rotation in Xamarin Forms
在我们的项目中,我们将以纵向模式锁定应用程序,目前没有问题。
现在我们希望有可能只旋转一些特定的页面或内容(以显示更大的图)。我在这个问题上搜索了很多线程
但没有找到明确的解决方案。对于 Andoid 和 Ios,是否有任何干净的方法可以在页面基础上指定方向?
我们还在研究仅旋转绘图视图的可能性,但我们在调整它的大小方面遇到了问题;
无论我为高度和宽度指定什么请求,图形始终显示为包含页面宽度和高度。
我们尝试在旋转之前反转大小:
rotatedView.WidthRequest = Height;
rotatedView.HeightRequest = Width;
rotatedView.Rotate(90)
contentView.Content = rotatedView;
并通过强加旋转后的纵横比然后缩放将其缩小:
rotatedView.WidthRequest = Width;
double ratio = Height / Width;
rotatedView.HeightRequest = Width / ratio;
rotatedView.Rotation = 90;
rotatedView.ScaleTo(ratio)
contentView.Content = graphRot;
旋转后的视图与原始页面保持相同的宽高比,宽度等于页面高度,反之亦然。
任何提示将不胜感激
更新
关于视图旋转,我可以通过将所有内容放在相对布局中来实现。这样我就可以自由定义视图大小等于旋转的容器大小。
我已经在我正在处理的应用程序中实施了一个解决方案。我的用例是我想锁定纵向,除非我在 Video Player 中。下面的代码是我完成这项任务的方式。
对于iOS:
您需要覆盖 AppDelegate.cs 中的 GetSupportedInterfaceOrientations
并在其中添加一些逻辑。
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
{
UIInterfaceOrientationMask supportedOrientation;
if (_AllowRotations == true)
{
supportedOrientation = UIInterfaceOrientationMask.AllButUpsideDown;
}
else
{
supportedOrientation = UIInterfaceOrientationMask.Portrait;
}
return supportedOrientation;
}
对于Android:
要在 Android 上设置正确的标志,您需要在 LaunchActivity.cs 中设置适当的标志的方法。
if (allowRotations == true)
{
RequestedOrientation = ScreenOrientation.Sensor;
}
else
{
RequestedOrientation = ScreenOrientation.Portrait;
}
如果您想从 Xamarin.Forms
调用它们,我建议将它们放在某种依赖服务中。每个 class 中的 allowrotations 变量是根据我从 VideoPlayerRenderer
使用的事件设置的,但您也可以从依赖服务中设置它们。
我通过这种方式解决了视图旋转问题:
/// <summary>
/// Rotates an element by 90 or 270 degrees. It is required that you put a RelativeLayout (no parameters needed)
/// around it and call this method on the element (i.e. in onAppearing).
/// </summary>
private void SetLandscape(VisualElement element, bool ccw = false)
{
element.Rotation = ccw ? 270.0 : 90.0;
RelativeLayout.SetHeightConstraint(element, Constraint.RelativeToParent(layout => layout.Width));
RelativeLayout.SetWidthConstraint(element, Constraint.RelativeToParent(layout => layout.Height));
RelativeLayout.SetYConstraint(element, Constraint.RelativeToParent(layout => (layout.Height - layout.Width) / 2));
RelativeLayout.SetXConstraint(element, Constraint.RelativeToParent(layout => (layout.Width - layout.Height) / 2));
}
由于使用了委托,这甚至可以继续进行布局更改。
约束也可以在Xaml中定义,但是,减法会很棘手,所以我找到了另一种方法,通过操纵旋转锚点。看起来很有趣但有效 - 最后我使用了这个:
<RelativeLayout>
<Grid Rotation="90" AnchorX="0" AnchorY="0"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}">
</Grid>
</RelativeLayout>
在我们的项目中,我们将以纵向模式锁定应用程序,目前没有问题。 现在我们希望有可能只旋转一些特定的页面或内容(以显示更大的图)。我在这个问题上搜索了很多线程 但没有找到明确的解决方案。对于 Andoid 和 Ios,是否有任何干净的方法可以在页面基础上指定方向?
我们还在研究仅旋转绘图视图的可能性,但我们在调整它的大小方面遇到了问题; 无论我为高度和宽度指定什么请求,图形始终显示为包含页面宽度和高度。 我们尝试在旋转之前反转大小:
rotatedView.WidthRequest = Height;
rotatedView.HeightRequest = Width;
rotatedView.Rotate(90)
contentView.Content = rotatedView;
并通过强加旋转后的纵横比然后缩放将其缩小:
rotatedView.WidthRequest = Width;
double ratio = Height / Width;
rotatedView.HeightRequest = Width / ratio;
rotatedView.Rotation = 90;
rotatedView.ScaleTo(ratio)
contentView.Content = graphRot;
旋转后的视图与原始页面保持相同的宽高比,宽度等于页面高度,反之亦然。
任何提示将不胜感激
更新
关于视图旋转,我可以通过将所有内容放在相对布局中来实现。这样我就可以自由定义视图大小等于旋转的容器大小。
我已经在我正在处理的应用程序中实施了一个解决方案。我的用例是我想锁定纵向,除非我在 Video Player 中。下面的代码是我完成这项任务的方式。
对于iOS:
您需要覆盖 AppDelegate.cs 中的 GetSupportedInterfaceOrientations
并在其中添加一些逻辑。
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
{
UIInterfaceOrientationMask supportedOrientation;
if (_AllowRotations == true)
{
supportedOrientation = UIInterfaceOrientationMask.AllButUpsideDown;
}
else
{
supportedOrientation = UIInterfaceOrientationMask.Portrait;
}
return supportedOrientation;
}
对于Android:
要在 Android 上设置正确的标志,您需要在 LaunchActivity.cs 中设置适当的标志的方法。
if (allowRotations == true)
{
RequestedOrientation = ScreenOrientation.Sensor;
}
else
{
RequestedOrientation = ScreenOrientation.Portrait;
}
如果您想从 Xamarin.Forms
调用它们,我建议将它们放在某种依赖服务中。每个 class 中的 allowrotations 变量是根据我从 VideoPlayerRenderer
使用的事件设置的,但您也可以从依赖服务中设置它们。
我通过这种方式解决了视图旋转问题:
/// <summary>
/// Rotates an element by 90 or 270 degrees. It is required that you put a RelativeLayout (no parameters needed)
/// around it and call this method on the element (i.e. in onAppearing).
/// </summary>
private void SetLandscape(VisualElement element, bool ccw = false)
{
element.Rotation = ccw ? 270.0 : 90.0;
RelativeLayout.SetHeightConstraint(element, Constraint.RelativeToParent(layout => layout.Width));
RelativeLayout.SetWidthConstraint(element, Constraint.RelativeToParent(layout => layout.Height));
RelativeLayout.SetYConstraint(element, Constraint.RelativeToParent(layout => (layout.Height - layout.Width) / 2));
RelativeLayout.SetXConstraint(element, Constraint.RelativeToParent(layout => (layout.Width - layout.Height) / 2));
}
由于使用了委托,这甚至可以继续进行布局更改。
约束也可以在Xaml中定义,但是,减法会很棘手,所以我找到了另一种方法,通过操纵旋转锚点。看起来很有趣但有效 - 最后我使用了这个:
<RelativeLayout>
<Grid Rotation="90" AnchorX="0" AnchorY="0"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}">
</Grid>
</RelativeLayout>