本文實例為大家分享了Android實現(xiàn)光點模糊漸變的自旋轉(zhuǎn)圓環(huán)效果,供大家參考,具體內(nèi)容如下
項目中需要實現(xiàn)的效果圖如下:
可以這個表盤看到中間部分都是沒有什么難點的,主要是周圍圓環(huán)的三種效果:
1.漸變色
2.尖端的白點模糊效果
3.路徑繪制
最終實現(xiàn)的效果圖如下:
完美實現(xiàn)了三點要求。
實現(xiàn)思路:
1.首先是黑色底色圓環(huán)的繪制(黑色圈是固定不變的)。
2.在繪制好黑色底色圓環(huán)之后再繪制漸變色圓弧(藍綠部分)。
3.最后繪制小星星部分,使用一張模糊圖片得到bitmap,并通過PathMeasure進行路徑繪制。
代碼實現(xiàn):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
/** * Created by jiangzn on 17/2/3. */ public class RoundLightBarView extends ImageView { private int mTotalWidth, mTotalHeight; private int mCenterX, mCenterY; //底色畫筆 private Paint mCirclePaint; //進度條畫筆 private Paint mProgressPaint; //圓點畫筆 private Paint mbitmapPaint; private Matrix mMatrix; // 矩陣,用于對圖片進行一些操作 private float [] pos; // 當前點的實際位置 private float [] tan; // 當前點的tangent值,用于計算圖片所需旋轉(zhuǎn)的角度 private int mCircleR; private Context mContext; //距離外圍的邊距 private float interval ; private int startAngle = 1 ; //球 private Bitmap mLititleBitmap; // 圓點圖片 public RoundLightBarView(Context context, AttributeSet attrs, int defStyleAttr) { super (context, attrs, defStyleAttr); } public RoundLightBarView(Context context, AttributeSet attrs) { super (context, attrs); mContext = context; interval = DensityUtils.px2dip(mContext, 50 ); //初始化畫筆 initPaint(); //初始化bitmap initBitmap(); } private void initBitmap() { mMatrix= new Matrix(); pos = new float [ 2 ]; tan = new float [ 2 ]; mLititleBitmap= ((BitmapDrawable) getResources() .getDrawable(R.mipmap.white_round)) .getBitmap(); } private void initPaint() { //畫黑底的深色圓畫筆 mCirclePaint = new Paint(); //抗鋸齒 mCirclePaint.setAntiAlias( true ); // 防抖動 mCirclePaint.setDither( true ); // 開啟圖像過濾,對位圖進行濾波處理。 mCirclePaint.setFilterBitmap( true ); mCirclePaint.setColor(Color.BLACK); //空心圓 mCirclePaint.setStyle(Paint.Style.STROKE); //圓半徑 mCircleR = DensityUtils.px2dip(mContext, 20 ); mCirclePaint.setStrokeWidth(mCircleR); //畫彩色圓弧的畫筆 mProgressPaint = new Paint(); //抗鋸齒 mProgressPaint.setAntiAlias( true ); // 防抖動 mProgressPaint.setDither( true ); // 開啟圖像過濾,對位圖進行濾波處理。 mProgressPaint.setFilterBitmap( true ); mProgressPaint.setColor(Color.BLUE); //空心圓 mProgressPaint.setStyle(Paint.Style.STROKE); //設置筆刷樣式為原型 mProgressPaint.setStrokeCap(Paint.Cap.ROUND); //設置圓弧粗 mProgressPaint.setStrokeWidth(mCircleR); //將繪制的內(nèi)容顯示在第一次繪制內(nèi)容之上 mProgressPaint.setXfermode( new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); //圓點畫筆 mbitmapPaint = new Paint(); mbitmapPaint.setXfermode( new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); mbitmapPaint.setStyle(Paint.Style.FILL); mbitmapPaint.setAntiAlias( true ); } @Override protected void onDraw(Canvas canvas) { super .onDraw(canvas); //canvas去鋸齒 canvas.setDrawFilter( new PaintFlagsDrawFilter( 0 , Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); //畫底色圓 canvas.drawCircle(mCenterX, mCenterY, mCenterX - mCircleR - interval, mCirclePaint); //畫進度條 int colorSweep[] = {Color.TRANSPARENT, Color.parseColor( "#3bbaea" ),Color.parseColor( "#7ac9d3" ),Color.parseColor( "#7cc9d0" )}; //設置漸變色 sweepGradient = new SweepGradient(mCenterX, mCenterY, colorSweep, null ); //按照圓心旋轉(zhuǎn) Matrix matrix = new Matrix(); matrix.setRotate(startAngle, mCenterX, mCenterY); sweepGradient.setLocalMatrix(matrix); mProgressPaint.setShader(sweepGradient); canvas.drawArc( new RectF( 0 + mCircleR + interval, 0 + mCircleR + interval, mTotalWidth - mCircleR - interval, mTotalHeight - mCircleR - interval), 2 + startAngle, 350 , false , mProgressPaint); startAngle++; if (startAngle == 360 ) { startAngle = 1 ; } //繪制白色小星星 Path orbit = new Path(); //通過Path類畫一個90度(180—270)的內(nèi)切圓弧路徑 orbit.addArc( new RectF( 0 + mCircleR + interval, 0 + mCircleR + interval, mTotalWidth - mCircleR - interval, mTotalHeight - mCircleR - interval) , 2 + startAngle, 350 ); // 創(chuàng)建 PathMeasure PathMeasure measure = new PathMeasure(orbit, false ); measure.getPosTan(measure.getLength() * 1 , pos, tan); mMatrix.reset(); mMatrix.postScale( 2 , 2 ); mMatrix.postTranslate(pos[ 0 ] - mLititleBitmap.getWidth() , pos[ 1 ] - mLititleBitmap.getHeight() ); // 將圖片繪制中心調(diào)整到與當前點重合 canvas.drawBitmap(mLititleBitmap, mMatrix, mbitmapPaint); //繪制球 mbitmapPaint.setColor(Color.WHITE); //繪制實心小圓圈 canvas.drawCircle(pos[ 0 ], pos[ 1 ], 5 , mbitmapPaint); //啟動繪制 postInvalidateDelayed( 10 ); } SweepGradient sweepGradient; @Override protected void onSizeChanged( int w, int h, int oldw, int oldh) { super .onSizeChanged(w, h, oldw, oldh); mTotalWidth = w; mTotalHeight = h; mCenterX = mTotalWidth / 2 ; mCenterY = mTotalHeight / 2 ; } } |
總結(jié):
總體實現(xiàn)難度并不大,復習了自定義View和canvas的知識點。
其中需要重視的點在繪圖層需要注意給畫筆添加覆蓋模式:setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)),將繪制的內(nèi)容顯示在第一次繪制的內(nèi)容之上,還有一個比較難的點是PathMeasure進行對bitmap的路徑收集和方向控制并繪制小星星的過程:
1
2
3
4
5
6
7
8
9
10
|
// 創(chuàng)建 PathMeasure PathMeasure measure = new PathMeasure(orbit, false ); measure.getPosTan(measure.getLength() * 1 , pos, tan); mMatrix.reset(); mMatrix.postScale( 2 , 2 ); mMatrix.postTranslate(pos[ 0 ] - mLititleBitmap.getWidth() , pos[ 1 ] - mLititleBitmap.getHeight() ); // 將圖片繪制中心調(diào)整到與當前點重合 canvas.drawBitmap(mLititleBitmap, mMatrix, mbitmapPaint); //繪制球 mbitmapPaint.setColor(Color.WHITE); //繪制實心小圓圈 canvas.drawCircle(pos[ 0 ], pos[ 1 ], 5 , mbitmapPaint); |
源碼下載:Android實現(xiàn)光點模糊漸變的自旋轉(zhuǎn)圓環(huán)特效
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/qq_22770457/article/details/54882052