# Xamarin Forms 進度條控件
本文翻譯:http://xamlnative.com/2016/04/14/xamarin-forms-a-simple-circular-progress-control/ 里面都是胡說的,如果看不懂可以聯系郵箱
源代碼:https://github.com/billreiss/xamlnative/tree/master/XamarinForms/CircularProgress
最近作者需要做一個簡單的圓形的等待控件在一個Xamarin Forms應用,效果可以看

<!--more-->
<div id="toc"></div>
看起來很容易做,不知道怎么微軟就沒有弄個這么好看,微軟沒有,我們來直接做,看起來這個很簡單
原來的進度條是一個線,沒有UWP那個ring,我要做一個,可以使用本地控制、自定義渲染器渲染、使用組件里面弄很多我之前做的、到Nuget找,這些都覺得不是我要的。
看到他們沒有,我就很高興,我可以做一個很厲害的,自然這里我是原文的那個,寫了Xaml的大神
我首先拿出一個本子,我應該弄矢量圖形,在Xamarin原生還沒有,我會為每個平臺定制渲染,所以他不支持我不能使用,我想到使用圖片,矢量圖片,既然想要圖片我如何讓很多圖片看起來是一個

我想到簡單使用兩圖,實際對稱兩圖是表示4圖,不停覆蓋的兩個圖片表示進度,兩個圖片顏色不同


圖片可以在:https://github.com/billreiss/xamlnative/tree/master/XamarinForms/CircularProgress/CircularProgress/CircularProgress.Droid/Resources/drawable
兩個保存格式Png圖片,一個圖表示0-50%,我們叫第一圖“completed”,第二“pending”,顏色深的是第一,進度我們需要一個completed,兩個pending,我們先放completed,然后在它上面放pending,在pending對面放pending,第一個圖在代碼叫“progress1”,第二“background1”,第二個覆蓋第一個,第三個pending旋轉180,總的一個藍色圓,這是0%

25%:我們旋轉pending第二個,可以讓看到下面的圖,這個我們覆蓋原來的pending因為顏色一樣,所以我們就可以看到25%

50%:我們需要改變,兩個completed,一個pending,pending覆蓋completed,但是只是覆蓋一個,他們的層次:
- completed
- pending
- completed
可以讓pending覆蓋右邊的completed,超過50%讓pending右旋
如果覺得上面說的還是不知道,可以看代碼
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace CircularProgress
{
public class CircularProgressControl : Grid
{
View progress1;
View progress2;
View background1;
View background2;
public CircularProgressControl()
{
progress1 = CreateImage("progress_done");
background1 = CreateImage("progress_pending");
background2 = CreateImage("progress_pending");
progress2 = CreateImage("progress_done");
HandleProgressChanged(1, 0);
}
private View CreateImage(string v1)
{
var img = new Image();
img.Source = ImageSource.FromFile(v1 + ".png");
this.Children.Add(img);
return img;
}
public static BindableProperty ProgressProperty =
BindableProperty.Create("Progress", typeof(double), typeof(CircularProgressControl), 0d, propertyChanged: ProgressChanged);
private static void ProgressChanged(BindableObject bindable, object oldValue, object newValue)
{
var c = bindable as CircularProgressControl;
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); }
}
}
}
```
我們需要把圖片放在不同平臺的文件夾,ios放在Resources文件夾,Android放在 AndroidResource
我們把控件放MainPage.xaml
```xml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CircularProgress.MainPage"
xmlns:local="clr-namespace:CircularProgress" BackgroundColor="White">
<Grid>
<local:CircularProgressControl x:Name="progressControl" Progress="0" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="60" HeightRequest="60"/>
</Grid>
</ContentPage>
```
我們讓time進度加0.1每0.02s
```csharp
namespace CircularProgress
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
Xamarin.Forms.Device.StartTimer(TimeSpan.FromSeconds(.02), OnTimer);
}
private bool OnTimer()
{
var progress = (progressControl.Progress + .1) ;
if (progress > 1) progress = 0;
progressControl.Progress = progress;
return true;
}
}
}
```
不使用自定義渲染,可以在各個平臺沒有使用厲害的技術覆蓋兩個圖做出從0-100%,可以使用不同角度表示0.001
本文:http://blog.csdn.net/lindexi_gd
- Introduction
- 控件
- Win10 UWP Intro to controls and events
- win10 UWP Controls by function
- win10 uwp App-to-app communication 應用通信
- win10 UWP 使用MD5算法
- win10 UWP 全屏
- win10 uwp 使用油墨輸入
- 三種方式設置特定設備UWP XAML view
- win10 uwp iot
- win10 uwp 活動磁貼
- win 10 UWP 標簽
- Xamarin Forms 進度條控件
- win10 UWP MessageDialog 和 ContentDialog
- win10 uwp 俄羅斯方塊
- win10 UWP Hmac
- win10 UWP 單元測試
- win10 uwp 判斷文件存在
- win10 UWP 標題欄后退
- win10 uwp 分治法
- win10 UWP 應用設置
- win10 uwp BadgeLogo 顏色
- win10 uwp json
- win10 uwp Window.Current.Dispatcher中Current為null
- win10 uwp 無法附加到CoreCLR
- win10 uwp 自定義控件 SplitViewItem
- win10 uwp ContentDialog 點確定不關閉
- win10 uwp smms圖床
- win10 uwp 從StorageFile獲取文件大小
- win10 uwp 如何讓WebView標識win10手機
- win10 uwp 上傳Nuget
- win10 uwp 手動鎖Bitlocker
- win10 uwp 圓角按鈕
- win10 uwp 入門
- win10 uwp 切換主題
- win10 uwp 隨著數字變化顏色控件
- win10 uwp 設置啟動窗口大小 獲取窗口大小
- win10 uwp 簡單MasterDetail
- win10 uwp 異步進度條
- win10 uwp 訪問解決方案文件
- C# 7.0
- win10 uwp InkCanvas控件數據綁定
- win10 uwp 列表模板選擇器
- win10 uwp 隱藏實時可視化
- win10 uwp 讀取文本ASCII錯誤
- Visual studio 創建項目失敗vstemplate
- Visual Studio 自定義項目模板
- win10 uwp 車表盤 徑向規
- win10 uwp 截圖 獲取屏幕顯示界面保存圖片
- win10 uwp 獲得焦點改變
- win10 uwp 應用轉后臺清理內存
- win10 uwp 隱私聲明
- win10 uwp 打包第三方字體到應用
- win10 uwp 九幽圖床
- win10 uwp 興趣線
- win10 uwp 右擊浮出窗在點擊位置
- win10 uwp 保存用戶選擇文件夾
- win10 uwp 打電話
- visual studio 2015 warning MSB3246
- win10 uwp 繪圖 Line 控件使用
- win10 uwp 存放網絡圖片到本地
- win10 uwp 判斷本地ip
- win10 uwp 彈起鍵盤不隱藏界面元素
- win10 uwp Markdown
- C# 設計模式 責任鏈
- win10 uwp 顯示SVG
- win10 uwp 網絡編程
- win10 uwp HttpClient post錯誤
- win10 uwp win2d
- win10 uwp 布局
- win10 uwp 初始屏幕
- win10 uwp dataGrid
- win10 uwp 魔力鬼畜
- win10 uwp如何使用DataTemplate
- win10 uwp 多語言
- win10 uwp CSDN閱讀 源代碼
- win10 uwp 語音
- win10 uwp 動畫
- win10 uwp 顏色轉換
- win10 uwp 獲得Slider拖動結束的值
- Windows 10「設置」應用完整MS-Settings快捷方式匯總
- win10 uwp 用廣告賺錢
- win10 uwp 快捷鍵
- win10 UWP MvvmLight入門
- win10 uwp 標題欄
- win10 uwp 從Type 使用構造
- win10 uwp ImageSourece 和Byte[] 相互轉換
- win10 uwp 驗證TextBox
- C# 使用Emit深克隆