大家肯定遇到過或将要遇到加載大資料的時候,如果出現長時間的空白等待,一般人的概念會是:難道卡死了?
作為一個懂技術的挨踢技術,即使你明知道資料量太大正在加載,但是假如看不到任何動靜,自己覺得還是一種很不好的體驗。
之前做項目的時候有這方面的要求,我的前輩們早已給出了完美的解決方案。最近自己在努力學習,今天拿出來與大家一起分享,我想一定會有幫助的。看過之後大家會佩服我的前輩的,呵呵,好,廢話少說,下面開始。
因為怕自己班門弄斧,是以在網上先查了資料,确定很難找到這樣的執行個體才敢拿出來與大家見面。不過确實也找到了一個相似效果的案例,但那位高手用的全是前台實作,而我的前輩是在背景寫了一個類BusyDecorator,用起來更加友善。喜歡前台xaml實作的可以去看一下那位高手的代碼:http://blog.csdn.net/qqamoon/article/details/7001693 他的代碼我沒做試驗,看他的那個實作效果跟我的是一樣的。
我的陋代碼又要上台表現了,諸位扶好眼鏡框了哈~~
首先我們需要定義一些屬性用來儲存位置,大小,角度,透明度之類:
/// <summary>
/// 條的數量
/// </summary>
int _elementCount;
/// <summary>
/// 圓的半徑
/// </summary>
double _radious = 10;
/// <summary>
/// 執行動畫的DispatcherTimer
/// </summary>
DispatcherTimer _animationTimer;
/// <summary>
/// 目前條的索引位置
/// </summary>
int _currentElementIndex = 0;
/// <summary>
/// 需要變換的透明度個數
/// </summary>
int _opacityCount;
/// <summary>
/// 透明度間的間隔
/// </summary>
double _opacityInterval;
/// <summary>
/// 透明度
/// </summary>
double _opacity;
/// <summary>
/// 最小透明度
/// </summary>
double _minOpacity;
/// <summary>
/// 條的數組
/// </summary>
object[] _elements;
/// <summary>
/// 畫布
/// </summary>
private Canvas _canvas;
View Code
由于我們是定義在一個類BusyDecorator裡面,是以需要在構造函數裡定義最初的靜态畫布效果。然後利用計時器控制動畫的啟動與停止。
重點便是靜态畫布的設計與Timer_Tick事件的實作。
我的前輩給出的靜态畫布設計如下:
private void CreateElements(Canvas canvas, double Left, double Top)
{
_elementCount = 12;
_opacity = 1;
_minOpacity = 0.3;
double surplusOpacity = _opacity - _minOpacity;
_opacityCount = (int)(_elementCount * 0.5);
_opacityInterval = surplusOpacity / _opacityCount;
_elements = new object[_elementCount];
for (int i = 0; i < _elementCount; i++)
{
Rectangle rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Black);
rect.Width = 5;
rect.Height = 5;
rect.RadiusX = 2;
rect.RadiusY = 2;
if (i < _opacityCount)
{
rect.Opacity = _opacity - i * _opacityInterval;
}
else
{
rect.Opacity = _minOpacity;
}
rect.SetValue(Canvas.LeftProperty, Left + _radious * Math.Cos(360 / _elementCount * i * Math.PI / 180));
rect.SetValue(Canvas.TopProperty, Top - 2.5 - _radious * Math.Sin(360 / _elementCount * i * Math.PI / 180));
rect.RenderTransform = new RotateTransform(360 - 360 / _elementCount * i, 0, 2.5);
canvas.Children.Add(rect);
_elements[i] = rect;
}
_currentElementIndex = 0;
}
接下來就是Timer_Tick事件了,一般人想不到這樣處理吧:
private void _animationTimer_Tick(object sender, EventArgs e)
{
try
{
_currentElementIndex--;
_currentElementIndex = _currentElementIndex < 0 ? _elements.Length - 1 : _currentElementIndex;
int opacitiedCount = 0;
for (int i = _currentElementIndex; i < _currentElementIndex + _elementCount; i++)
{
int j = i > _elements.Length - 1 ? i - _elements.Length : i;
if (opacitiedCount < _opacityCount)
{
((Rectangle)_elements[j]).Opacity = _opacity - opacitiedCount * _opacityInterval;
opacitiedCount++;
}
else
{
((Rectangle)_elements[j]).Opacity = _minOpacity;
}
}
}
catch (Exception ex)
{ }
}
好了,重點結束後就是剩下的構造函數BusyDecorator了:
public BusyDecorator(Canvas canvas)
{
this._canvas = canvas;
_animationTimer = new DispatcherTimer();
_animationTimer.Interval = TimeSpan.FromMilliseconds(40);
_animationTimer.Tick += new EventHandler(_animationTimer_Tick);
CreateElements(canvas, canvas.Width / 2, canvas.Height / 2);
}
注意:此構造函數由于用到了canvas.width和canvas.height,是以,前台定義canvas時一定要設定其width和height屬性。
然後是啟動動畫與停止動畫事件:
public void StartDecorator()
{
_canvas.Visibility = Visibility.Visible;
_animationTimer.Start();
}
public void StopDecorator()
{
_canvas.Visibility = Visibility.Hidden;
_animationTimer.Stop();
}
好了,類BusyDecorator設計好了,下面做一個執行個體測試一下吧:
做一個前台頁面:
<Window x:Class="testFlowDocument.zhuanquanFlash"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="zhuanquanFlash" Height="300" Width="300">
<Grid>
<Canvas Name="canvas_bu" Width="200" Height="200" VerticalAlignment="Top" Background="LightBlue">
</Canvas>
<Button Name="btn_start" Content="開始" Height="50" VerticalAlignment="Bottom" Click="Button_Click" />
</Grid>
</Window>
背景代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace testFlowDocument
{
/// <summary>
/// zhuanquanFlash.xaml 的互動邏輯
/// </summary>
public partial class zhuanquanFlash : Window
{
public zhuanquanFlash()
{
InitializeComponent();
busy = new BusyDecorator(this.canvas_bu);
}
BusyDecorator busy;
bool isstart = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (isstart == false)
{
busy.StartDecorator();
isstart = true;
this.btn_start.Content = "停止";
}
else
{
busy.StopDecorator();
isstart = false;
this.btn_start.Content = "開始";
}
}
}
}
靜态效果圖:
PS:如何快速制作動态gif圖?像上邊連結位址裡的那樣的gif圖。不會photoshop,求推薦好使工具~~
本文位址:http://www.cnblogs.com/jying/p/3230391.html 轉載請寫明出處~~
ok,到此為止,謝謝大家捧場~~
個人小站歡迎來踩:駕校教練評價平台 | 為愛豆砌照片牆