将 Xamarin.Forms 元素旋转 90 度(横向显示而不旋转整个页面或设备)
Rotate Xamarin.Forms element by 90 degrees (display in landscape without rotating the whole page or device)
页面上只有一个元素,如带有子元素的网格,应旋转 90 度,同时通常与其周围的堆栈布局等对齐。
有一个 Rotation="90"
属性。它有效,但对齐方式似乎是按其原始方向计算的,并且不考虑现在交换的高度和宽度。因此,如果该元素不是正方形,它现在会与其他元素重叠或部分绘制在屏幕之外。这对我来说没有多大意义。怎么做才对?
将元素放入RelativeLayout
,可以自由定位元素。
<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>
仅仅交换了宽度和高度后,元素位置仍然是错误的,因为它是围绕原来的中心旋转的(AnchorX
和Y
默认是0.5
)。这可以通过 (Width - Height) / 2
的翻译来解决(参见下面的代码隐藏解决方案),但是我们通过将旋转锚点更改为它的一个角来变得更容易,如上所示。
/// <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));
}
这两种解决方案在运行时更改布局后仍能正常工作。
页面上只有一个元素,如带有子元素的网格,应旋转 90 度,同时通常与其周围的堆栈布局等对齐。
有一个 Rotation="90"
属性。它有效,但对齐方式似乎是按其原始方向计算的,并且不考虑现在交换的高度和宽度。因此,如果该元素不是正方形,它现在会与其他元素重叠或部分绘制在屏幕之外。这对我来说没有多大意义。怎么做才对?
将元素放入RelativeLayout
,可以自由定位元素。
<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>
仅仅交换了宽度和高度后,元素位置仍然是错误的,因为它是围绕原来的中心旋转的(AnchorX
和Y
默认是0.5
)。这可以通过 (Width - Height) / 2
的翻译来解决(参见下面的代码隐藏解决方案),但是我们通过将旋转锚点更改为它的一个角来变得更容易,如上所示。
/// <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));
}
这两种解决方案在运行时更改布局后仍能正常工作。