日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android自定义View——动态ProgressBar之模仿360加速球

發(fā)布時(shí)間:2023/12/10 Android 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android自定义View——动态ProgressBar之模仿360加速球 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  在之前一篇文章中我們講解了三種ProgressBar的做法,詳見(jiàn)—>《Android 自定義View——自定義ProgressBar 》。這一節(jié)中我們模仿360加速球制作一個(gè)動(dòng)態(tài)ProgressBar。
  
當(dāng)然制作之前,我們先來(lái)看看360加速球是什么樣子的:
  

  通過(guò)上面的動(dòng)圖,我們了解到360加速球是什么樣子的,現(xiàn)在我們開(kāi)始來(lái)制作自己的ProgressBar。這里用到了之前兩篇博客的知識(shí)。大家可以參考學(xué)習(xí):
  《Android 自定義View——Path的使用 》
  《Android 自定義View——自定義ProgressBar 》
  《Android PorterDuff.Mode圖形混合處理 》

  不廢話了,接下來(lái)進(jìn)入正題……

原理解析

  首先我們定義有一個(gè)Bitmap,給這個(gè)Bitmap對(duì)象定義一個(gè)Canvas畫布,我們將內(nèi)容繪制在這個(gè)Bitmap上,然后再將Bitmap添加到View的Canvas上。
  Bitmap的Canvas上,我們要繪制一個(gè)圓形,這個(gè)圓形代表最大進(jìn)度,然后繪制圓形內(nèi)的“波動(dòng)的水”。這個(gè)波動(dòng)的水我們要通過(guò)處理圖形混合的PorterDuff.Mode來(lái)實(shí)現(xiàn)。“波動(dòng)的水”的實(shí)現(xiàn),是通過(guò)Path中定義貝塞爾曲線完成的。我們繪制一條貝塞爾曲線,通過(guò)moveTo()和lineTo()方法,將貝塞爾曲線閉合,然后通過(guò)Handler操縱貝塞爾曲線波動(dòng)。通過(guò)PorterDuff.Mode的PorterDuff.Mode.SRC_IN模式上層只顯示圓圓形重合的部分,從而實(shí)現(xiàn)在貝塞爾曲線在圓形內(nèi)波動(dòng)。

代碼實(shí)現(xiàn)

我們看代碼,再通過(guò)代碼解析:

public class MyProgressAnimation extends View {private int width;//設(shè)置高private int height;//設(shè)置高private Bitmap bitmap;//定義Bitmapprivate Canvas bitmapCanvas;//定義Bitmap的畫布private Path mPath; //定義路徑private Paint mPathPaint;//定義路徑的畫筆private Paint mPaintCircle;//定義圓形的畫筆private Paint mPaintText; //定義繪制文字的畫筆//設(shè)置進(jìn)度private int maxProgress = 100;private int currentProgress = 0;public int getMaxProgress() {return maxProgress;}public void setMaxProgress(int maxProgress) {this.maxProgress = maxProgress;}public int getCurrentProgress() {return currentProgress;}public void setCurrentProgress(int currentProgress) {this.currentProgress = currentProgress;invalidate();//實(shí)時(shí)更新進(jìn)度}private int count = 0;private static final int NEED_INVALIDATE = 0X6666;//操作UI主線程private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case NEED_INVALIDATE://更新時(shí)間count += 5;if (count > 80) {count = 0;}invalidate();sendEmptyMessageDelayed(NEED_INVALIDATE, 50);break;}}};public MyProgressAnimation(Context context, AttributeSet attrs) {super(context, attrs);//初始化一個(gè)路徑mPath = new Path();//初始化繪制路徑的畫筆mPathPaint = new Paint();mPathPaint.setAntiAlias(true);mPathPaint.setColor(Color.argb(0xff, 0xff, 0x69, 0x5a));mPathPaint.setStyle(Paint.Style.FILL);//設(shè)置為填充,默認(rèn)為填充,這里我們還是定義下mPathPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));mPaintCircle = new Paint();mPaintCircle.setAntiAlias(true);mPaintCircle.setColor(Color.argb(0xff, 0xf8, 0x8e, 0x8b));mPaintText = new Paint();mPaintText.setAntiAlias(true);mPaintText.setColor(Color.argb(0xff, 0xFF, 0xF3, 0xF7));mPaintText.setTextAlign(Paint.Align.CENTER);mPaintText.setTextSize(50);handler.sendEmptyMessageDelayed(NEED_INVALIDATE, 50);}public MyProgressAnimation(Context context) {super(context);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);super.onMeasure(widthMeasureSpec, heightMeasureSpec);width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);setMeasuredDimension(width, height);//設(shè)置寬和高bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);bitmapCanvas = new Canvas(bitmap);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//繪制Bitmap上的圓形bitmapCanvas.drawCircle(width / 2, height / 2, 150, mPaintCircle);//通過(guò)Path繪制貝塞爾曲線mPath.reset();mPath.moveTo(width, (height / 2 + 150) - (currentProgress * 300f / maxProgress));mPath.lineTo(width, height / 2 + 200);mPath.lineTo(count, height / 2 + 200);mPath.lineTo(count, (height / 2 + 150) - (currentProgress * 300f / maxProgress));for (int i = 0; i < 10; i++) {mPath.rQuadTo(20, 5, 40, 0);mPath.rQuadTo(20, -5, 40, 0);}mPath.close();//將貝塞爾曲線繪制到Bitmap的Canvas上bitmapCanvas.drawPath(mPath, mPathPaint);//將Bitmap繪制到View的Canvas上bitmapCanvas.drawText(currentProgress * 100f / maxProgress + "%", width / 2, height / 2, mPaintText);canvas.drawBitmap(bitmap, 0, 0, null);} }

  

  通過(guò)這張圖片我們可以更好的理解繪制原理。
繪制紅色區(qū)域的圓形:

//繪制Bitmap上的圓形bitmapCanvas.drawCircle(width / 2, height / 2, 150, mPaintCircle);

繪制Path軌跡區(qū)域:
  注意:這里我們繪制路徑是最后使用貝塞爾曲線封閉的。然后Path封閉路徑的高度是變化的。

//通過(guò)Path繪制貝塞爾曲線mPath.reset();mPath.moveTo(width, (height / 2 + 150) - (currentProgress * 300f / maxProgress));//通過(guò)此處根據(jù)進(jìn)度設(shè)置高度mPath.lineTo(width, height / 2 + 200);mPath.lineTo(count, height / 2 + 200);mPath.lineTo(count, (height / 2 + 150) - (currentProgress * 300f / maxProgress));//通過(guò)此處根據(jù)進(jìn)度設(shè)置高度for (int i = 0; i < 10; i++) {mPath.rQuadTo(20, 5, 40, 0);mPath.rQuadTo(20, -5, 40, 0);}mPath.close();

通過(guò)效果,只保留上層的重疊部分:

//在初始化繪制路徑的畫筆上加入這個(gè)效果mPathPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

控件使用

1. 在布局中定義控件和按鈕,點(diǎn)擊按鈕,進(jìn)度開(kāi)始自動(dòng)增加。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.example.administrator.mywidgetdemo.activity.MyProgressAnimationActivity"><Button android:id="@+id/button_start_myprogressanomation"android:layout_width="match_parent"android:layout_height="wrap_content" /><com.example.administrator.mywidgetdemo.widget.MyProgressAnimation android:id="@+id/myprogressanomation"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

2. Activity中點(diǎn)擊按鈕后增加進(jìn)度。

public class MyProgressAnimationActivity extends Activity {private Button mButton;private MyProgressAnimation myprogressanomation;private static final int PROGRESS= 0X0003;//定義一個(gè)進(jìn)度private int progress;private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case PROGRESS:progress++;if (progress <= 100) {myprogressanomation.setCurrentProgress(progress);sendEmptyMessageDelayed(PROGRESS, 100);}break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_my_progress_anomation);mButton = (Button) findViewById(R.id.button_start_myprogressanomation);myprogressanomation= (MyProgressAnimation) findViewById(R.id.myprogressanomation);mButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {handler.sendEmptyMessageDelayed(PROGRESS, 1000);}});} }

3. 實(shí)現(xiàn)效果如下:

總結(jié)

以上是生活随笔為你收集整理的Android自定义View——动态ProgressBar之模仿360加速球的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。