Android實(shí)現(xiàn)光點(diǎn)模糊漸變的自旋轉(zhuǎn)圓環(huán)特效
本文實(shí)例為大家分享了Android實(shí)現(xiàn)光點(diǎn)模糊漸變的自旋轉(zhuǎn)圓環(huán)效果,供大家參考,具體內(nèi)容如下
項(xiàng)目中需要實(shí)現(xiàn)的效果圖如下:
可以這個(gè)表盤看到中間部分都是沒有什么難點(diǎn)的,主要是周圍圓環(huán)的三種效果:
1.漸變色
2.尖端的白點(diǎn)模糊效果
3.路徑繪制
最終實(shí)現(xiàn)的效果圖如下:
完美實(shí)現(xiàn)了三點(diǎn)要求。
實(shí)現(xiàn)思路:
1.首先是黑色底色圓環(huán)的繪制(黑色圈是固定不變的)。
2.在繪制好黑色底色圓環(huán)之后再繪制漸變色圓弧(藍(lán)綠部分)。
3.最后繪制小星星部分,使用一張模糊圖片得到bitmap,并通過PathMeasure進(jìn)行路徑繪制。
代碼實(shí)現(xiàn):
/** * Created by jiangzn on 17/2/3. */ public class RoundLightBarView extends ImageView { private int mTotalWidth, mTotalHeight; private int mCenterX, mCenterY; //底色畫筆 private Paint mCirclePaint; //進(jìn)度條畫筆 private Paint mProgressPaint; //圓點(diǎn)畫筆 private Paint mbitmapPaint; private Matrix mMatrix; // 矩陣,用于對圖片進(jìn)行一些操作 private float[] pos; // 當(dāng)前點(diǎn)的實(shí)際位置 private float[] tan; // 當(dāng)前點(diǎn)的tangent值,用于計(jì)算圖片所需旋轉(zhuǎn)的角度 private int mCircleR; private Context mContext; //距離外圍的邊距 private float interval ; private int startAngle = 1; //球 private Bitmap mLititleBitmap; // 圓點(diǎn)圖片 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); // 防抖動(dòng) mCirclePaint.setDither(true); // 開啟圖像過濾,對位圖進(jìn)行濾波處理。 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); // 防抖動(dòng) mProgressPaint.setDither(true); // 開啟圖像過濾,對位圖進(jìn)行濾波處理。 mProgressPaint.setFilterBitmap(true); mProgressPaint.setColor(Color.BLUE); //空心圓 mProgressPaint.setStyle(Paint.Style.STROKE); //設(shè)置筆刷樣式為原型 mProgressPaint.setStrokeCap(Paint.Cap.ROUND); //設(shè)置圓弧粗 mProgressPaint.setStrokeWidth(mCircleR); //將繪制的內(nèi)容顯示在第一次繪制內(nèi)容之上 mProgressPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); //圓點(diǎn)畫筆 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); //畫進(jìn)度條 int colorSweep[] = {Color.TRANSPARENT, Color.parseColor("#3bbaea"),Color.parseColor("#7ac9d3"),Color.parseColor("#7cc9d0")}; //設(shè)置漸變色 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類畫一個(gè)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)整到與當(dāng)前點(diǎn)重合 canvas.drawBitmap(mLititleBitmap, mMatrix, mbitmapPaint);//繪制球 mbitmapPaint.setColor(Color.WHITE); //繪制實(shí)心小圓圈 canvas.drawCircle(pos[0], pos[1], 5, mbitmapPaint); //啟動(dòng)繪制 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é):
總體實(shí)現(xiàn)難度并不大,復(fù)習(xí)了自定義View和canvas的知識(shí)點(diǎn)。
其中需要重視的點(diǎn)在繪圖層需要注意給畫筆添加覆蓋模式:setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)),將繪制的內(nèi)容顯示在第一次繪制的內(nèi)容之上,還有一個(gè)比較難的點(diǎn)是PathMeasure進(jìn)行對bitmap的路徑收集和方向控制并繪制小星星的過程:
// 創(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)整到與當(dāng)前點(diǎn)重合 canvas.drawBitmap(mLititleBitmap, mMatrix, mbitmapPaint);//繪制球 mbitmapPaint.setColor(Color.WHITE); //繪制實(shí)心小圓圈 canvas.drawCircle(pos[0], pos[1], 5, mbitmapPaint);
源碼下載:Android實(shí)現(xiàn)光點(diǎn)模糊漸變的自旋轉(zhuǎn)圓環(huán)特效
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android自定義View實(shí)現(xiàn)圓環(huán)顏色選擇器
- 利用Android模仿微信攝像圓環(huán)進(jìn)度效果實(shí)例
- Android自定義帶動(dòng)畫的半圓環(huán)型進(jìn)度效果
- Android自定義view繪制圓環(huán)占比動(dòng)畫
- Android實(shí)現(xiàn)動(dòng)態(tài)圓環(huán)的圖片頭像控件
- Android自定義View實(shí)現(xiàn)圓環(huán)交替效果
- Android中自定義View實(shí)現(xiàn)圓環(huán)等待及相關(guān)的音量調(diào)節(jié)效果
- Android自定義View之酷炫圓環(huán)(二)
- Android自定義View之酷炫數(shù)字圓環(huán)
- Android開發(fā)筆記之:在ImageView上繪制圓環(huán)的實(shí)現(xiàn)方法
相關(guān)文章
Flutter app頁面路由以及路由攔截的實(shí)現(xiàn)
本篇介紹了介紹了Flutter如何使用路由來實(shí)現(xiàn)頁面的跳轉(zhuǎn),從而簡化頁面之間的耦合,并可以實(shí)現(xiàn)路由攔截。2021-06-06Android中Fragmen首選項(xiàng)使用自定義的ListPreference的方法
Android中Fragmen的首選項(xiàng)可以使用自定義的ListPreference,這樣Fragment的PreferenceFragment就可以更方便地保存配置信息,需要的朋友可以參考下2016-05-05Android使用Notification實(shí)現(xiàn)寬視圖通知欄(二)
這篇文章主要為大家詳細(xì)介紹了Android使用Notification實(shí)現(xiàn)寬視圖通知欄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12Android開發(fā)自定義TextView省略號(hào)樣式的方法
這篇文章主要介紹了Android開發(fā)自定義TextView省略號(hào)樣式的方法,結(jié)合實(shí)例形式分析了Android文本控件TextView相關(guān)屬性與字符串操作技巧,需要的朋友可以參考下2017-10-10Android Studio中使用lambda表達(dá)式的方法
這篇文章主要介紹了Android Studio中使用lambda表達(dá)式的方法,需要的朋友可以參考下2017-06-06Android自定義wheelview實(shí)現(xiàn)滾動(dòng)日期選擇器
這篇文章主要為大家詳細(xì)介紹了Android自定義wheelview實(shí)現(xiàn)滾動(dòng)日期選擇器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Android編程之ActionBar Tabs用法實(shí)例分析
這篇文章主要介紹了Android編程之ActionBar Tabs用法,結(jié)合實(shí)例形式分析了ActionBar Tabs的功能及Tab切換不同的Fragment的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-03-03android實(shí)現(xiàn)簡單底部導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)簡單底部導(dǎo)航欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07