C#自定义控件(圆形进度条)Xamarin Forms

9

我希望知道使用Xamarin Forms创建类似于这张图片的最佳方法:

enter image description here

我从未制作过这样的东西。我知道如何使用进度条,但不知道“圆形进度条”。

感谢您的帮助和任何提示。

编辑:如果您有一个插件/nuget可以做到这一点,那很酷,但我想知道如何自己做这件事。我从未制作过这样的东西。


1
你有iOS和Android的解决方案吗? - AbsoluteSith
6个回答

4

我知道这是一个老帖子,但像我这样的一些人在搜索圆形进度时会遇到这个主题。

Andreas Hennig制作了一个很好的插件,适用于iOS和Android,您可以从nuget安装它:Progress Ring Control Plugin

XAML

  1. 添加XAML命名空间:

    xmlns:control="clr-namespace:ProgressRingControl.Forms.Plugin;assembly=ProgressRing.Forms.Plugin"

  2. 添加xaml:

    <control:ProgressRing RingThickness="20" Progress="0.5"/>

您可以在以下位置找到它:

https://github.com/AndreasHennig/ProgressRingPlugin


我该如何在ProgressRing中间显示进度条的数量? - Fatikhan Gasimov

3

2
我试图为Xamarin Forms找到一个库,但是没有发现同时支持Android和iOS的库。此外,没有太多类型的进度指示器可供选择。最终,我使用SkiaSharp在Xamarin Forms中构建了自己的自定义径向进度指示器小部件,它支持Android和iOS。
教程链接:https://medium.com/@kpshinde25/custom-radial-progress-indicator-in-xamarin-forms-c7ed81840c1e 您可以根据需要修改代码以拥有圆形、多圆圈指示器等功能。

1
我发现这篇文章对于 Xamarin Forms 的“圆形进度条”有迄今为止最好的解决方案。基本上,您使用两个半圆形图像,并根据进度旋转它们,我认为这是一个非常创造性和优雅的解决方案。不需要自定义渲染器!

虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。仅有链接的答案如果链接页面发生更改可能会变得无效。 - Sanket
这个的代码仍然可以在这里找到 https://github.com/billreiss/xamlnative/tree/master/XamarinForms/CircularProgress - Jonathan Parker

1

1
我喜欢James Montemagno的教程,但是渲染器只适用于Android。我也想为IOS做一些东西。 - user4071320
你的问题是关于如何创建圆形进度条,解决方案是使用“自定义渲染器”。你可以使用https://components.xamarin.com/gettingstarted/radialprogress组件。 - Abdul Muhaymin
你知道是否有一种方法可以在 UWP 上完成这个吗? - Emil
@AbdulMuhaymin,radialprogress 是原生解决方案,对吧。问题是 Xamarin Forms 应该支持 iOS、Android。 - LCJ
你没有回答这个问题,而是发布了一个使用自定义渲染器的解决方案。 - LeRoy

0

来自https://github.com/billreiss/xamlnative/tree/master/XamarinForms/CircularProgress的代码

public class CircularProgress : Grid
{
    View progress1;
    View progress2;
    View background1;
    View background2;
    public CircularProgress()
    {
        var baseUrl = "https://github.com/billreiss/xamlnative/raw/master/XamarinForms/CircularProgress/CircularProgress/CircularProgress.Droid/Resources/drawable/";
        
        progress1 = CreateImage($"{baseUrl}progress_done.png");
        background1 = CreateImage($"{baseUrl}progress_pending.png");
        background2 = CreateImage($"{baseUrl}progress_pending.png");
        progress2 = CreateImage($"{baseUrl}progress_done.png");
        HandleProgressChanged(1, 0);
    }

    private View CreateImage(string imageName)
    {
        var img = new Image();
        img.Source = ImageSource.FromUri(new Uri(imageName));
        this.Children.Add(img);
        return img;
    }

    public static BindableProperty ProgressProperty =
BindableProperty.Create(nameof(Progress), typeof(double), typeof(CircularProgress), 0d, propertyChanged: ProgressChanged);

    private static void ProgressChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var c = bindable as CircularProgress;
        c.HandleProgressChanged(Clamp((double)oldValue, 0, 1), Clamp((double)newValue, 0, 1));
    }

    static double Clamp(double value, double min, double max)
    {
        if (value <= max && value >= min) return value;
        else if (value > max) return max;
        else return min;
    }

    private void HandleProgressChanged(double oldValue, double p)
    {
        if (p < .5)
        {
            if (oldValue >= .5)
            {
                // this code is CPU intensive so only do it if we go from >=50% to <50%
                background1.IsVisible = true;
                progress2.IsVisible = false;
                background2.Rotation = 180;
                progress1.Rotation = 0;
            }
            double rotation = 360 * p;
            background1.Rotation = rotation;
        }
        else
        {
            if (oldValue < .5)
            {
                // this code is CPU intensive so only do it if we go from <50% to >=50%
                background1.IsVisible = false;
                progress2.IsVisible = true;
                progress1.Rotation = 180;
            }
            double rotation = 360 * p;
            background2.Rotation = rotation;
        }
    }

    public double Progress
    {
        get { return (double)this.GetValue(ProgressProperty); }
        set { SetValue(ProgressProperty, value); }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接