如何实现环形Loading
来源:互联网 发布:c#做windows窗口程序 编辑:程序博客网 时间:2024/05/22 14:07
看一看效果
此控件设置了常用的外观属性 例如主题色彩 线条宽度 内圆大小 外圆大小都可以调节
提供2个对外的方法Start() Stop()控制控件的行为 调用Start()动画开始 Stop()结束动画还原到初始状态
以下是字段 该控件继承自Control类
代码
1 private Timer _Timer;
2 private bool _IsLoading = false;
3 private int _NumberOfSpoke = 12;//辐条数目
4 private int _ProgressValue = 0;//进度值
5 private PointF _CenterPointF;
6 private int _InnerCircleRadius = 5;
7 private int _OutnerCircleRadius = 10;
8 private Color _ThemeColor = Color.DimGray;
9 private int _Speed = 100;
10 private Color[] _Colors;
11 private int _lineWidth = 3;
2 private bool _IsLoading = false;
3 private int _NumberOfSpoke = 12;//辐条数目
4 private int _ProgressValue = 0;//进度值
5 private PointF _CenterPointF;
6 private int _InnerCircleRadius = 5;
7 private int _OutnerCircleRadius = 10;
8 private Color _ThemeColor = Color.DimGray;
9 private int _Speed = 100;
10 private Color[] _Colors;
11 private int _lineWidth = 3;
辅助方法
代码
1 //画带有圆角线帽和指定颜色的直线(带alpha)
2 private void DrawLine(Graphics g, PointF pointF1, PointF pointF2, Color color)
3 {
4 //强制资源管理 (管理非托管资源)
5 using (Pen pen = new Pen(new SolidBrush(color),_lineWidth))
6 {
7 //指定线帽子
8 pen.StartCap = LineCap.Round;
9 pen.EndCap = LineCap.Round;
10 g.DrawLine(pen, pointF1, pointF2);
11 }
12 }
13 //根据中心点 半径 和角度,获取从中心点出发的线段终点
14 private PointF GetPointF(PointF centerPointF, int r, double angle)
15 {
16 double A = Math.PI * angle / 180;//(angle/360)*2PI
17 float xF = centerPointF.X + r * (float)Math.Cos(A);
18 float yF = centerPointF.Y + r * (float)Math.Sin(A);
19
20 return (new PointF(xF, yF));
21 }
22 //根据辐条数量和主题颜色返回一个Color数组
23 private Color[] GetColors(Color color, int spokeMember, bool isLoading)
24 {
25 Color[] colors = new Color[spokeMember];
26 int offseAlpha = 255 / spokeMember;//alpha偏差量
27 if (isLoading == true)
28 {
29 for (int i = 0; i < spokeMember; i++)
30 {
31 colors[i] = Color.FromArgb(i * offseAlpha, color);//反向储存 形成顺时针旋转效果
32 }
33 }
34 else
35 {
36 for (int i = 0; i < spokeMember; i++)
37 {
38 colors[i] = color;
39 }
40 }
41 return colors;
42 }
43 private void _Timer_Tick(object sender, EventArgs e)
44 {
45 _ProgressValue++;
46 if (_ProgressValue > 11)
47 _ProgressValue = 0;
48 Invalidate();
49 }
2 private void DrawLine(Graphics g, PointF pointF1, PointF pointF2, Color color)
3 {
4 //强制资源管理 (管理非托管资源)
5 using (Pen pen = new Pen(new SolidBrush(color),_lineWidth))
6 {
7 //指定线帽子
8 pen.StartCap = LineCap.Round;
9 pen.EndCap = LineCap.Round;
10 g.DrawLine(pen, pointF1, pointF2);
11 }
12 }
13 //根据中心点 半径 和角度,获取从中心点出发的线段终点
14 private PointF GetPointF(PointF centerPointF, int r, double angle)
15 {
16 double A = Math.PI * angle / 180;//(angle/360)*2PI
17 float xF = centerPointF.X + r * (float)Math.Cos(A);
18 float yF = centerPointF.Y + r * (float)Math.Sin(A);
19
20 return (new PointF(xF, yF));
21 }
22 //根据辐条数量和主题颜色返回一个Color数组
23 private Color[] GetColors(Color color, int spokeMember, bool isLoading)
24 {
25 Color[] colors = new Color[spokeMember];
26 int offseAlpha = 255 / spokeMember;//alpha偏差量
27 if (isLoading == true)
28 {
29 for (int i = 0; i < spokeMember; i++)
30 {
31 colors[i] = Color.FromArgb(i * offseAlpha, color);//反向储存 形成顺时针旋转效果
32 }
33 }
34 else
35 {
36 for (int i = 0; i < spokeMember; i++)
37 {
38 colors[i] = color;
39 }
40 }
41 return colors;
42 }
43 private void _Timer_Tick(object sender, EventArgs e)
44 {
45 _ProgressValue++;
46 if (_ProgressValue > 11)
47 _ProgressValue = 0;
48 Invalidate();
49 }
构造函数和重写方法
代码
1 public CircleLoading()
2 {
3 InitializeComponent();
4 SetStyle(ControlStyles.UserPaint, true);
5 SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
6 SetStyle(ControlStyles.ResizeRedraw, true);
7 SetStyle(ControlStyles.SupportsTransparentBackColor, true);
8
9 _Timer = new Timer();
10 _Timer.Tick+=new EventHandler(_Timer_Tick);
11 _Timer.Interval = _Speed;
12 _Colors = GetColors(_ThemeColor, _NumberOfSpoke, _IsLoading);
13
14 }
15 protected override void OnPaint(PaintEventArgs pe)
16 {
17 _CenterPointF = new PointF(this.Width / 2, this.Height / 2);
18 if (_NumberOfSpoke > 0)
19 {
20 pe.Graphics.SmoothingMode = SmoothingMode.HighQuality;
21 double offsetAngle = (double)360 / _NumberOfSpoke;
22 double currentAngle = _ProgressValue * offsetAngle;
23 for (int i = 0; i < _NumberOfSpoke; i++)
24 {
25 DrawLine(pe.Graphics, GetPointF(_CenterPointF, _InnerCircleRadius, currentAngle), GetPointF(_CenterPointF, _OutnerCircleRadius, currentAngle), _Colors[i]);
26 currentAngle += offsetAngle;
27 }
28 }
29 base.OnPaint(pe);
30 }
2 {
3 InitializeComponent();
4 SetStyle(ControlStyles.UserPaint, true);
5 SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
6 SetStyle(ControlStyles.ResizeRedraw, true);
7 SetStyle(ControlStyles.SupportsTransparentBackColor, true);
8
9 _Timer = new Timer();
10 _Timer.Tick+=new EventHandler(_Timer_Tick);
11 _Timer.Interval = _Speed;
12 _Colors = GetColors(_ThemeColor, _NumberOfSpoke, _IsLoading);
13
14 }
15 protected override void OnPaint(PaintEventArgs pe)
16 {
17 _CenterPointF = new PointF(this.Width / 2, this.Height / 2);
18 if (_NumberOfSpoke > 0)
19 {
20 pe.Graphics.SmoothingMode = SmoothingMode.HighQuality;
21 double offsetAngle = (double)360 / _NumberOfSpoke;
22 double currentAngle = _ProgressValue * offsetAngle;
23 for (int i = 0; i < _NumberOfSpoke; i++)
24 {
25 DrawLine(pe.Graphics, GetPointF(_CenterPointF, _InnerCircleRadius, currentAngle), GetPointF(_CenterPointF, _OutnerCircleRadius, currentAngle), _Colors[i]);
26 currentAngle += offsetAngle;
27 }
28 }
29 base.OnPaint(pe);
30 }
对外方法start stop
代码
1 public void Start()
2 {
3 _IsLoading = true;
4 _Colors = GetColors(_ThemeColor, _NumberOfSpoke, _IsLoading);
5 _Timer.Start();
6 }
7 public void Stop()
8 {
9 _Timer.Stop();
10 _IsLoading = false;
11 _Colors = GetColors(_ThemeColor, _NumberOfSpoke, _IsLoading);
12 Invalidate();
13 }
2 {
3 _IsLoading = true;
4 _Colors = GetColors(_ThemeColor, _NumberOfSpoke, _IsLoading);
5 _Timer.Start();
6 }
7 public void Stop()
8 {
9 _Timer.Stop();
10 _IsLoading = false;
11 _Colors = GetColors(_ThemeColor, _NumberOfSpoke, _IsLoading);
12 Invalidate();
13 }
属性
代码
1 public int Speed
2 {
3 get { return _Speed; }
4 set
5 {
6 _Speed = value;
7 _Timer.Interval = _Speed;
8 }
9 }
10 public int SpokesMember
11 {
12 get { return _NumberOfSpoke; }
13 set
14 {
15 _NumberOfSpoke = value;
16 Invalidate();
17 }
18 }
19 public int InnerCircleRadius
20 {
21 get { return _InnerCircleRadius; }
22 set
23 {
24 _InnerCircleRadius = value;
25 Invalidate();
26 }
27 }
28 public int OutnerCircleRadius
29 {
30 get { return _OutnerCircleRadius; }
31 set
32 {
33 _OutnerCircleRadius = value;
34 Invalidate();
35 }
36 }
37 public Color ThemeColor
38 {
39 get { return _ThemeColor; }
40 set
41 {
42 _ThemeColor = value;
43 _Colors = GetColors(_ThemeColor, _NumberOfSpoke, _IsLoading);
44 Invalidate();
45 }
46 }
47 public int LineWidth
48 {
49 get { return _lineWidth; }
50 set
51 {
52 _lineWidth = value;
53 Invalidate();
54 }
55 }
56 public bool IsActive
57 {
58 get
59 {
60 return _Timer.Enabled;
61 }
62 }
2 {
3 get { return _Speed; }
4 set
5 {
6 _Speed = value;
7 _Timer.Interval = _Speed;
8 }
9 }
10 public int SpokesMember
11 {
12 get { return _NumberOfSpoke; }
13 set
14 {
15 _NumberOfSpoke = value;
16 Invalidate();
17 }
18 }
19 public int InnerCircleRadius
20 {
21 get { return _InnerCircleRadius; }
22 set
23 {
24 _InnerCircleRadius = value;
25 Invalidate();
26 }
27 }
28 public int OutnerCircleRadius
29 {
30 get { return _OutnerCircleRadius; }
31 set
32 {
33 _OutnerCircleRadius = value;
34 Invalidate();
35 }
36 }
37 public Color ThemeColor
38 {
39 get { return _ThemeColor; }
40 set
41 {
42 _ThemeColor = value;
43 _Colors = GetColors(_ThemeColor, _NumberOfSpoke, _IsLoading);
44 Invalidate();
45 }
46 }
47 public int LineWidth
48 {
49 get { return _lineWidth; }
50 set
51 {
52 _lineWidth = value;
53 Invalidate();
54 }
55 }
56 public bool IsActive
57 {
58 get
59 {
60 return _Timer.Enabled;
61 }
62 }
- 如何实现环形Loading
- android如何实现环形缓冲区
- 如何实现一个环形进度条
- 在一读一写限制下,无锁环形队列如何实现?
- 一读一写情况下,无锁环形队列如何实现?
- Android:如何实现老版优酷客户端三级环形菜单
- Android如何实现老版优酷客户端三级环形菜单
- 一读一写情况下,无锁环形队列如何实现?
- 环形缓冲器Java实现
- 环形队列实现原理
- 环形缓冲器Java实现
- 环形缓冲区的实现
- 环形缓冲区的实现
- 环形缓冲区的实现
- android实现环形进度条
- 环形buffer的实现
- 环形队列类实现
- 简单环形队列实现
- IndexRegisterAction
- 《Effective java》读书笔记9——线程并发
- FlexLib
- 一个程序员在Elance上的外包经验分享
- mysql的空值与NULL的区别
- 如何实现环形Loading
- 从洗手间细节到企业文化—企业信息化应该具体什么样的精益化管理
- Android4.0.4编程日记(4)--List单击Intent跳转并获取数据
- VC编译选项 MT MTd
- DUT 1009 很久以前的第一次写排序+二分
- 前沿程序员推荐的几个国外开源网站
- DUT 1006 视力表 (打印图形的模拟题)
- hdu1013 Digital Roots
- C++的多态性