国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android自定義View葉子旋轉(zhuǎn)完整版(六)

2019-12-12 03:18:24
字體:
供稿:網(wǎng)友

上一篇實現(xiàn)多葉子飄動旋轉(zhuǎn),今天完成最后的功能。

1、添加右側(cè)旋轉(zhuǎn)楓葉

2、添加滑動條效果,顯示百分比

3、修復(fù)葉子飄出邊框問題

1、添加右側(cè)旋轉(zhuǎn)葉子

Bitmap turnBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.fengshan, null)).getBitmap(); int turnLeafAngle = 0; private void setTurnLeaf(Canvas canvas) {  Matrix matrix = new Matrix();  turnLeafAngle = turnLeafAngle + 3;  matrix.postTranslate((width - rightCircleWidth/2 - turnBitmap.getWidth()/2),    (height - rightCircleWidth/2 - turnBitmap.getHeight()/2));  matrix.postRotate(turnLeafAngle,      width - rightCircleWidth/2 - turnBitmap.getWidth()/2 + turnBitmap.getWidth()/2,     height - rightCircleWidth/2 - turnBitmap.getHeight()/2 + turnBitmap.getHeight()/2);  canvas.drawBitmap(turnBitmap, matrix, new Paint()); }

代碼很明確,首先通過Matrix.postTranslate(float dx, float dy)把turnBitMap定位到最右側(cè)圓圈

再通過Matrix.postRotate(float degress, float dx, float dy);設(shè)置旋轉(zhuǎn)角度,每次角度+3°

其中degress為旋轉(zhuǎn)角度,(dx,dy)為旋轉(zhuǎn)中心點坐標(biāo)

2、添加滑動效果

原理就是覆蓋一層不同顏色的圖層。根據(jù)當(dāng)前百分比,分別畫一個半圓,畫一個正方形

a、定義一個圓形Rectf(為什么不是半圓?因為畫圓弧的其實角度從水平線右側(cè)開始)

progressArcRectf = new RectF(0, 0, height, height);

b、定義一個長方形Rectf,長方形x坐標(biāo)起點即時圓形半徑

progressRectf = new RectF(height/2,  0, width, height);

c、畫出圓弧Canvas.drawArc(Rectf rectf, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

startAngle:起始角度,默認(rèn)從右側(cè)水平線開始

sweepAngle:為旋轉(zhuǎn)的角度,順時針旋轉(zhuǎn)

useCenter:true只畫出弧線,false則畫出圓心到弧線的區(qū)域

//畫滑動后的背景條int currentProgressWidht = currentProgress * (width - borderWidth)/100;if(currentProgressWidht < leftCircleWidth/2) {  //angle取值范圍0~90  int angle = 90 * currentProgressWidht / (leftCircleWidth/2);  // 起始的位置  int startAngle = 180 - angle;  // 掃過的角度  int sweepAngle = 2 * angle;  canvas.drawArc(progressArcRectf, startAngle, sweepAngle, false, progressBgPaint);}else {  //畫左邊半圓形滑過部分  canvas.drawArc(progressArcRectf, 90, 180, false, progressBgPaint);  progressRectf.left = borderWidth + leftCircleWidth/2;  progressRectf.right = borderWidth + currentProgressWidht;  //畫中間滑過部分  canvas.drawRect(progressRectf, progressBgPaint); }

給LeafView.java添加一個

 public void setCurrentProgress(int currentProgress) {  this.currentProgress = currentProgress; }

3、修復(fù)葉子飄動范圍

這個簡單,就是設(shè)置葉子的rect坐標(biāo)起點+邊框距離

賦上所有代碼

1、activity_leaf.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content_leaf" android:layout_width="match_parent" android:layout_height="match_parent">  <RelativeLayout   android:layout_width="226dp"   android:layout_height="45dp">    <com.zjcpo.t170313_countdowntimer.LeafView     android:id="@+id/leafView"     android:layout_width="226dp"     android:layout_height="45dp"     android:layout_centerHorizontal="true"     />  </RelativeLayout></RelativeLayout>

2、LeafView.java

import android.content.Context;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.util.Log;import android.view.View;import java.util.LinkedList;import java.util.List;import java.util.Random;import java.util.jar.Attributes;/** * Created by jiemiao.zhang on 2017-3-15. */public class LeafView extends View { private String TAG = "--------LeafView"; private Resources mResources; //背景圖、葉子 private Bitmap mLeafBitmap, bgBitmap, turnBitmap; //整個控件的寬度和高度 private int width, height; //最外層邊框?qū)挾?private int borderWidth; //右側(cè)圓形直徑 private int rightCircleWidth; //左側(cè)圓形直徑 private int leftCircleWidth; private Paint bgPaint; private RectF bgRect; private Rect bgDestRect; //進(jìn)度條實時背景 private Paint progressBgPaint; //進(jìn)度條左側(cè)半圓,進(jìn)度條中間長方形部分Rect private RectF progressArcRectf, progressRectf; //當(dāng)前百分比0~100 private int currentProgress = 0; //存放葉子lsit private List<Leaf> leafList; //葉子的寬和高 private int mLeafWidth, mLeafHeight; //葉子滑動一周的時間5秒 private final static long cycleTime = 5000; //葉子數(shù)量 private final static int leafNumber = 6; public LeafView(Context context, AttributeSet attrs) {  super(context, attrs);  mResources = getResources();  mLeafBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.leaf, null)).getBitmap();  mLeafWidth = mLeafBitmap.getWidth();  mLeafHeight = mLeafBitmap.getHeight();  turnBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.fengshan, null)).getBitmap();  bgBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.leaf_kuang, null)).getBitmap();  bgPaint = new Paint();  bgPaint.setColor(mResources.getColor(R.color.bg_color));  //進(jìn)度條實時背景  progressBgPaint = new Paint();  progressBgPaint.setColor(mResources.getColor(R.color.progress_bg_color));  //獲取所有葉子的信息,放入list  leafList = getLeafs(leafNumber); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {  super.onSizeChanged(w, h, oldw, oldh);  width = w;  height = h;  borderWidth = height * 10/64;  rightCircleWidth = width * 62/303;  leftCircleWidth = height - 2 * borderWidth;  bgDestRect = new Rect(0, 0 , width, height);  bgRect = new RectF(0, 0 , width, height);  progressArcRectf = new RectF(borderWidth, borderWidth, height - borderWidth, height - borderWidth);  progressRectf = new RectF(borderWidth+(height-2*borderWidth)/2, borderWidth,          width-rightCircleWidth/2, height-borderWidth);  Log.i("leftMarginWidth", (borderWidth + leftCircleWidth/2) + ""); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  //畫背景顏色到畫布  canvas.drawRect(bgRect, bgPaint);  if(currentProgress <= 100) {   //畫葉子   int size = leafList.size();   for (int i=0; i<size; i++) {    Leaf leaf = leafList.get(i);    //獲取葉子坐標(biāo)    getLocation(leaf);    //獲取葉子旋轉(zhuǎn)角度    getRotate(leaf);    canvas.save();    Matrix matrix = new Matrix();    //設(shè)置滑動    matrix.postTranslate(leaf.x, leaf.y);    //設(shè)置旋轉(zhuǎn)    matrix.postRotate(leaf.rotateAngle, leaf.x + mLeafWidth / 2, leaf.y + mLeafHeight / 2);    //添加葉子到畫布    canvas.drawBitmap(mLeafBitmap, matrix, new Paint());    canvas.restore();    //畫滑動后的背景條    int currentProgressWidht = currentProgress * (width - borderWidth - rightCircleWidth/2)/100;    if(currentProgressWidht < leftCircleWidth/2) {     //angle取值范圍0~90     int angle = 90 * currentProgressWidht / (leftCircleWidth/2);     Log.i(TAG, "angle :" + angle);     // 起始的位置     int startAngle = 180 - angle;     // 掃過的角度     int sweepAngle = 2 * angle;     canvas.drawArc(progressArcRectf, startAngle, sweepAngle, false, progressBgPaint);    }else {     //畫左邊半圓形滑過部分     canvas.drawArc(progressArcRectf, 90, 180, false, progressBgPaint);     progressRectf.left = borderWidth + leftCircleWidth/2;     progressRectf.right = borderWidth + currentProgressWidht;     //畫中間滑過部分     canvas.drawRect(progressRectf, progressBgPaint);    }   }   //調(diào)用onDraw()重復(fù)滑動   if(currentProgress < 100) {    postInvalidate();   }  }  //畫背景圖片到畫布  canvas.drawBitmap(bgBitmap, null, bgDestRect, null);  //畫右邊選擇風(fēng)葉  setTurnLeaf(canvas);  //畫百分比  setText(canvas); } int turnLeafAngle = 0; private void setTurnLeaf(Canvas canvas) {  Matrix matrix = new Matrix();  turnLeafAngle = turnLeafAngle + 3;  matrix.postTranslate((width - rightCircleWidth/2 - turnBitmap.getWidth()/2),       (height - rightCircleWidth/2 - turnBitmap.getHeight()/2));  matrix.postRotate(turnLeafAngle,       width - rightCircleWidth/2 - turnBitmap.getWidth()/2 + turnBitmap.getWidth()/2,       height - rightCircleWidth/2 - turnBitmap.getHeight()/2 + turnBitmap.getHeight()/2);  canvas.drawBitmap(turnBitmap, matrix, new Paint()); } //顯示百分比數(shù)字,大于3%開始顯示,到50%停止滑動 private void setText(Canvas canvas) {  Paint paintText = new Paint();  paintText.setColor(Color.WHITE);  paintText.setTextSize(30);  int textX = currentProgress * width / 100;  textX = currentProgress < 50 ? (currentProgress * width / 100) : (width/2);  if(currentProgress > 3) {   canvas.drawText(currentProgress + "%", textX, height/2 + 10,paintText);  } } //獲取每片葉子在XY軸上的滑動值 private void getLocation(Leaf leaf) {  float betweenTime = leaf.startTime - System.currentTimeMillis();  //周期結(jié)束再加一個cycleTime  if(betweenTime < 0) {   leaf.startTime = System.currentTimeMillis() + cycleTime + new Random().nextInt((int) (cycleTime));   betweenTime = cycleTime;  }  //通過時間差計算出葉子的坐標(biāo)  float fraction = (float) betweenTime / cycleTime;  float x = (int)(width * fraction);  //防止葉子飄出邊框  leaf.x = x < borderWidth ? borderWidth : x;  float w = (float) ((float) 2 * Math.PI / width);  int y = (int) (18 * Math.sin(w * x)) + (height-mLeafHeight)/2;  //防止葉子飄出邊框  y = y > (height - borderWidth) ? (height - borderWidth) : y;  y = y < borderWidth ? borderWidth : y;  leaf.y = y; } //獲取每片葉子的旋轉(zhuǎn)角度 private void getRotate(Leaf leaf) {  float scale = ((leaf.startTime - System.currentTimeMillis())%cycleTime)/ (float)cycleTime;  int rotate = (int)(scale * 360);  leaf.rotateAngle = rotate; } private class Leaf {  // 葉子的坐標(biāo)  float x, y;  // 旋轉(zhuǎn)角度  int rotateAngle;  // 起始時間(ms)  long startTime; } private List<Leaf> getLeafs(int leafSize) {  List<Leaf> list = new LinkedList<Leaf>();  for (int i=0; i<leafSize; i++) {   list.add(getLeaf());  }  return list; } //使葉子初始時間有間隔 int addTime; private Leaf getLeaf() {  Random random = new Random();  Leaf leaf = new Leaf();  leaf.rotateAngle = random.nextInt(360);  addTime += random.nextInt((int) (cycleTime));  leaf.startTime = System.currentTimeMillis() + cycleTime + addTime;  return leaf; } public void setCurrentProgress(int currentProgress) {  this.currentProgress = currentProgress; }}3、LeafActivity.javapublic class LeafActivity extends Activity { private LeafView leafView; private int mProgress = 0; Handler mHandler = new Handler() {  public void handleMessage(Message msg) {   if (mProgress < 40) {    mProgress += 1;    // 隨機(jī)800ms以內(nèi)刷新一次    mHandler.sendEmptyMessageDelayed(1,      new Random().nextInt(800));    leafView.setCurrentProgress(mProgress);   } else {    mProgress += 1;    // 隨機(jī)1200ms以內(nèi)刷新一次    mHandler.sendEmptyMessageDelayed(1,      new Random().nextInt(100));    leafView.setCurrentProgress(mProgress);   }  }; }; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_leaf);  leafView = (LeafView) findViewById(R.id.leafView);  mHandler.sendEmptyMessageDelayed(1, 3000); }}

最后再看下效果

總結(jié)

看過前5篇的很好理解,用到的技術(shù)點之前都講到了。這篇主要就是幾個百分比函數(shù)的計算。

比如設(shè)置半圓時弧度如何計算,圓弧對應(yīng)的百分比,滑動區(qū)域長方形的起點坐標(biāo)計算,去掉邊框后的坐標(biāo)計算

畫半圓必須要有一個完整圓形Rect,因為drawArc()從右側(cè)半徑水平起始角度,順時針。然功能要求我們從左側(cè)圓形開始畫,所以要通過一個算法,假如當(dāng)前百分比為4%,需要畫30°的圓弧,那么起始角度為165°=180°-15°,畫出角度30%

通過matrix.postRotate()實現(xiàn)旋轉(zhuǎn)功能時,必須加上當(dāng)前view的坐標(biāo)及二分之一長寬

需要圖片等信息的可以從下面的Github地址下載,不過原文比較復(fù)雜

參考 https://github.com/Ajian-studio/GALeafLoading

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 都匀市| 象州县| 惠东县| 巴塘县| 浪卡子县| 潜江市| 清水河县| 萨迦县| 万全县| 武夷山市| 滨海县| 宝丰县| 桑日县| 普定县| 龙泉市| 临武县| 罗山县| 灵山县| 阿克苏市| 白银市| 行唐县| 辰溪县| 济阳县| 贺兰县| 乌兰察布市| 通州区| 福清市| 蒲江县| 柯坪县| 辽阳市| 连云港市| 阳信县| 霍邱县| 长汀县| 体育| 峨眉山市| 准格尔旗| 瑞安市| 水城县| 会东县| 花垣县|