【问题标题】:Vertical slider in Xamarin.forms?Xamarin.forms 中的垂直滑块?
【发布时间】:2017-08-15 19:36:45
【问题描述】:

我正在尝试在 Xamarin.forms 中实现垂直滑块。我知道我需要分别在 ios 和 android 中创建渲染类。对于 ios,我的渲染器似乎工作正常。对于 android,我关注链接 https://forums.xamarin.com/discussion/69933/vertical-slider。然而,上面链接中提供的解决方案给我留下了一个没有拇指的滑块。有什么方法可以在 Xamarin.forms 中为 android 实现垂直滑块?

【问题讨论】:

  • 在PCL中直接使用<Slider Rotation="90"/>不能解决你的问题吗?默认情况下,它有一个带滑块的拇指。
  • 不,它没有。在使用渲染器之前,我尝试过这样做。不确定它有什么问题。

标签: xamarin xamarin.android slider xamarin.forms


【解决方案1】:

我有同样的问题,并花了一些时间搜索。与其他评论者一样,我的解决方案是旋转滑块。事实证明,这是在 Forms 中做的相当挑剔的事情。旋转围绕中心点并在任何定位后应用,这就是为什么事情往往会偏离目标(或离开屏幕......)。我最终使用 RelativeLayout 来应用正确的大小和位置,并将其包装在 ContentView 中以使其美观且易于使用。

这样使用:

... 
xmlns:components="clr-namespace:YourNamespace.Components" 
...
<components:VerticalContentView>
    <Slider />
</components:VerticalContentView>

VerticalContentView 可以像任何其他 ContentView 一样使用。添加到其中的任何视图都将旋转 -90 度。可以使用 ContentRotation 属性自定义旋转。

请注意,任何视图都可以旋转,而不仅仅是滑块。

这是课程。

[ContentProperty("VerticalContent")]
public class VerticalContentView : ContentView
{
    public View VerticalContent 
    { 
        get => (View)GetValue(ContentProperty); 
        set => SetValue(ContentProperty, Verticalize(value)); 
    }

    public double ContentRotation { get; set; } = -90;

    private View Verticalize(View toBeRotated)
    {
        if (toBeRotated == null)
            return null;

        toBeRotated.Rotation = ContentRotation;
        var result = new RelativeLayout();

        result.Children.Add(toBeRotated,
        xConstraint: Constraint.RelativeToParent((parent) =>
        {
            return parent.X - ((parent.Height - parent.Width) / 2);
        }),
        yConstraint: Constraint.RelativeToParent((parent) =>
        {
            return (parent.Height / 2) - (parent.Width / 2);
        }),
        widthConstraint: Constraint.RelativeToParent((parent) =>
        {
            return parent.Height;
        }),
        heightConstraint: Constraint.RelativeToParent((parent) =>
        {
            return parent.Width;
        }));

        return result;
    }
}

它在 C# 中,因为我发现无法根据 XAML 中的父维度进行算术运算。

我对 Xamarin(以及一般的 XAML)还很陌生,所以这样做可能会产生我不知道的负面影响。欢迎任何批评。

【讨论】:

    【解决方案2】:

    这行得通,有点。它仍然有很多令人讨厌的怪异之处,但是,它的核心工作是:具有垂直滑块,彼此相邻对齐。

    <AbsoluteLayout x:Name="slidersAbs" HeightRequest="300" HorizontalOptions="CenterAndExpand" WidthRequest="800">
        <Slider Rotation="-90" Minimum="0" Maximum="50" Value="0"
            AbsoluteLayout.LayoutBounds="0,.5,300,50" AbsoluteLayout.LayoutFlags="PositionProportional"/>
        <Slider Rotation="-90" Minimum="0" Maximum="80" Value="0"
            AbsoluteLayout.LayoutBounds=".5,.5,300,50" AbsoluteLayout.LayoutFlags="PositionProportional"/>
        <Slider Rotation="-90" Minimum="0" Maximum="100" Value="0"
            AbsoluteLayout.LayoutBounds="1,.5,300,50" AbsoluteLayout.LayoutFlags="PositionProportional"/>
    </AbsoluteLayout>
    

    我从实验中收集到的一些东西:

    1. 我不得不将 WidthRequest 设置为一个非常高的数字,以使滑块完全水平间隔开;在 abs 布局上设置边框可能有助于理清那里发生的事情。
    2. 您会注意到只有位置 (X,Y) 是成比例的;如果你让高度/宽度保持不变,它会像你在其他布局方法中遇到的那样吓坏了,在这种布局方法中,高度和宽度会相互反转,但仍然与屏幕成反比,这是一团糟。您根本无法在旋转时使用宽度/高度比例。
    3. 你会认为疯狂的宽度和事情会导致某种滚动困境或其他冲突,但它实际上工作得很好。
    4. 我已将最大值设置为 50、80、100,因此很容易分辨哪个是哪个。正如您所希望的那样,0 放在每个的底部(不是顶部 - Rotation=90 将 0 放在顶部,-90 解决了这个问题),最后一个滑块显示在右侧。

    【讨论】:

      【解决方案3】:

      我就是这样做的。我认为是直观的,我不必担心坐标。 X 和 Y 仍然相对于所需的实际滑块左侧和顶部。 请注意,SetLayoutBounds 中的 Rectangle 边界故意交换了高度和宽度。

        Slider thisfader = new Slider();
        //coordinates swapped to accomodate rotation
        AbsoluteLayout.SetLayoutBounds(thisfader, new Rectangle(X, Y + Height, Height, Width));
        thisfader.AnchorX = 0; 
        thisfader.AnchorY = 0; //these set the rotation anchor on top left
        thisfader.Rotation = -90;
      
        AbsoluteLayout.Children.Add(thisfader);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多