【问题标题】:Xamarin Cross Platform Dual SliderXamarin 跨平台双滑块
【发布时间】:2015-12-04 21:06:18
【问题描述】:

有人听说过 Xamarin Forms 的双面滑块吗?我正在寻找,但似乎找不到。原生 Xamarin Forms Slider 非常漂亮,但它只支持 1 个标记。我正在寻找一个每边有两个标记的滑块。

有没有人听说过或知道如何扩展 Xamarin 控件以添加类似的功能。

在此问题上的任何帮助将不胜感激。

我在这里找到了范围滑块

https://components.xamarin.com/view/rangeslider

不幸的是,该控件具有 iOS 4 外观,无法根据我阅读的内容进行样式化或视觉更新。

【问题讨论】:

  • 您找到解决方案了吗?可以发帖吗?
  • 不,我最终在两条不同的线上使用了两个滑块,以达到我想要的效果。

标签: ios xamarin slider controls rangeslider


【解决方案1】:

这是 iOS 的一个实现。希望对您有所帮助!

public class UIRangeSlider : UIControl
{
    public nfloat MinValue;
    public nfloat MaxValue;
    public nfloat MinRange;
    public nfloat SelectedMinValue;
    public nfloat SelectedMaxValue;
    public Action<UIRangeSlider> ThumbChanged;

    private UIImageView minThumb, maxThumb, track, trackBackground;
    nfloat padding = 15.0f;
    bool maxThumbOn = false;
    bool minThumbOn = false;
    nfloat distanceFromCenter;

    public UIRangeSlider(CGRect frame)
        : base(frame)
    {
        trackBackground = new UIImageView(Resources.SliderTrackBackground.StretchableImage(1, 1));
        trackBackground.Center = Center;
        AddSubview(trackBackground);

        track = new UIImageView(Resources.SliderTrackGreen);
        track.Center = Center;
        AddSubview(track);

        minThumb = new UIImageView(Resources.SliderHandle, Resources.SliderHandle);
        minThumb.Frame = new CGRect(0, 0, Frame.Size.Height, Frame.Size.Height);
        minThumb.ContentMode = UIViewContentMode.Center;
        AddSubview(minThumb);

        maxThumb = new UIImageView(Resources.SliderHandle, Resources.SliderHandle);
        maxThumb.Frame = new CGRect(0, 0, Frame.Size.Height, Frame.Size.Height);
        maxThumb.ContentMode = UIViewContentMode.Center;
        AddSubview(maxThumb);
    }

    public override void LayoutSubviews()
    {
        base.LayoutSubviews();
        minThumb.Center = new CGPoint(XForValue(SelectedMinValue), Center.Y - Frame.Top);
        maxThumb.Center = new CGPoint(XForValue(SelectedMaxValue), Center.Y - Frame.Top);

        // minThumb.Layer.BorderColor = UIColor.Red.CGColor;
        // minThumb.Layer.BorderWidth = 1.0f;

        // maxThumb.Layer.BorderColor = UIColor.Red.CGColor;
        // maxThumb.Layer.BorderWidth = 1.0f;

        UpdateTrackHighlight();
    }

    private nfloat XForValue(nfloat val)
    {
        return (Frame.Size.Width - (padding * 2)) * ((val - MinValue) / (MaxValue - MinValue)) + padding;
    }

    private nfloat ValueForX(nfloat x)
    {
        return MinValue + (x - padding) / (Frame.Size.Width - (padding * 2)) * (MaxValue - MinValue);
    }

    public override bool ContinueTracking(UITouch uitouch, UIEvent uievent)
    {
        if (!minThumbOn && !maxThumbOn)
            return true;

        var touchPoint = uitouch.LocationInView(this);
        if (minThumbOn)
        {
            var xValue = (nfloat)Math.Max(XForValue(MinValue), Math.Min(touchPoint.X - distanceFromCenter, XForValue(SelectedMaxValue - MinRange)));
            var yValue = minThumb.Center.Y - Frame.Top;
            minThumb.Center = new CGPoint(xValue, yValue);
            SelectedMinValue = ValueForX(minThumb.Center.X);
        }

        if (maxThumbOn)
        {
            var xValue = (nfloat) Math.Min(XForValue(MaxValue), Math.Max(touchPoint.X - distanceFromCenter, XForValue(SelectedMinValue + MinRange)));
            var yValue = maxThumb.Center.Y - Frame.Top;
            maxThumb.Center = new CGPoint(xValue, yValue);
            SelectedMaxValue = ValueForX(maxThumb.Center.X);
        }

        UpdateTrackHighlight();
        this.SetNeedsLayout();

        if (ThumbChanged != null)
            ThumbChanged(this);

        return true;
    }

    public override bool BeginTracking(UITouch uitouch, UIEvent uievent)
    {
        var touchPoint = uitouch.LocationInView(this);

        if (minThumb.Frame.Contains(touchPoint))
        {
            minThumbOn = true;
            distanceFromCenter = touchPoint.X - minThumb.Center.X;
        }
        else if (maxThumb.Frame.Contains(touchPoint))
        {
            maxThumbOn = true;
            distanceFromCenter = touchPoint.X - maxThumb.Center.X;
        }

        return true;
    }

    public override void EndTracking(UITouch uitouch, UIEvent uievent)
    {
        minThumbOn = false;
        maxThumbOn = false;
    }

    private void UpdateTrackHighlight()
    {
        track.Frame = new CGRect(minThumb.Center.X, 
            maxThumb.Center.Y - (track.Frame.Height / 2),
            maxThumb.Center.X - minThumb.Center.X,
            track.Frame.Size.Height);

        // track.Layer.BorderColor = UIColor.Black.CGColor;
        // track.Layer.BorderWidth = 1.0f;

        trackBackground.Frame = new CGRect(1, 
            maxThumb.Center.Y - (trackBackground.Frame.Height / 2),
            Frame.Width-2, trackBackground.Frame.Size.Height);

        // trackBackground.Layer.BorderColor = UIColor.Red.CGColor;
        // trackBackground.Layer.BorderWidth = 1.0f;
    }
}

【讨论】:

  • 谢谢!!!我会检查一下。对于我当前的实现,我只为 Min 和 Max 使用两个单独的滑块,因为我找不到双滑块可接受的解决方案。
【解决方案2】:

答案是真的没有任何原生的东西,你可以尝试扩展原生滑块或将两个滑块堆叠在一起以获得所需的效果。

你也可以看看

https://components.xamarin.com/view/rangeslider

但它看起来很旧并且不容易扩展。

让我们去 Xamarin 给我们一个双滑块!!!还是elseee??!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    相关资源
    最近更新 更多