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

首頁 > 系統 > Android > 正文

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

2019-10-23 18:33:55
字體:
來源:轉載
供稿:網友

上一篇實現多葉子飄動旋轉,今天完成最后的功能。

1、添加右側旋轉楓葉

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

3、修復葉子飄出邊框問題

Android,View,葉子旋轉

1、添加右側旋轉葉子

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定位到最右側圓圈

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

其中degress為旋轉角度,(dx,dy)為旋轉中心點坐標

2、添加滑動效果

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

Android,View,葉子旋轉

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

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

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

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

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

startAngle:起始角度,默認從右側水平線開始

sweepAngle:為旋轉的角度,順時針旋轉

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

//畫滑動后的背景條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、修復葉子飄動范圍

這個簡單,就是設置葉子的rect坐標起點+邊框距離

賦上所有代碼

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; //最外層邊框寬度 private int borderWidth; //右側圓形直徑 private int rightCircleWidth; //左側圓形直徑 private int leftCircleWidth; private Paint bgPaint; private RectF bgRect; private Rect bgDestRect; //進度條實時背景 private Paint progressBgPaint; //進度條左側半圓,進度條中間長方形部分Rect private RectF progressArcRectf, progressRectf; //當前百分比0~100 private int currentProgress = 0; //存放葉子lsit private List<Leaf> leafList; //葉子的寬和高 private int mLeafWidth, mLeafHeight; //葉子滑動一周的時間5秒 private final static long cycleTime = 5000; //葉子數量 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));  //進度條實時背景  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);    //獲取葉子坐標    getLocation(leaf);    //獲取葉子旋轉角度    getRotate(leaf);    canvas.save();    Matrix matrix = new Matrix();    //設置滑動    matrix.postTranslate(leaf.x, leaf.y);    //設置旋轉    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);    }   }   //調用onDraw()重復滑動   if(currentProgress < 100) {    postInvalidate();   }  }  //畫背景圖片到畫布  canvas.drawBitmap(bgBitmap, null, bgDestRect, null);  //畫右邊選擇風葉  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()); } //顯示百分比數字,大于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();  //周期結束再加一個cycleTime  if(betweenTime < 0) {   leaf.startTime = System.currentTimeMillis() + cycleTime + new Random().nextInt((int) (cycleTime));   betweenTime = cycleTime;  }  //通過時間差計算出葉子的坐標  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; } //獲取每片葉子的旋轉角度 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 {  // 葉子的坐標  float x, y;  // 旋轉角度  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;    // 隨機800ms以內刷新一次    mHandler.sendEmptyMessageDelayed(1,      new Random().nextInt(800));    leafView.setCurrentProgress(mProgress);   } else {    mProgress += 1;    // 隨機1200ms以內刷新一次    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); }}

最后再看下效果

Android,View,葉子旋轉

總結

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

比如設置半圓時弧度如何計算,圓弧對應的百分比,滑動區域長方形的起點坐標計算,去掉邊框后的坐標計算

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

通過matrix.postRotate()實現旋轉功能時,必須加上當前view的坐標及二分之一長寬

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 额济纳旗| 金湖县| 南康市| 呼图壁县| 巴里| 新安县| 新野县| 太谷县| 夹江县| 鄂尔多斯市| 靖西县| 周至县| 涟源市| 若尔盖县| 绥芬河市| 万盛区| 广东省| 章丘市| 南阳市| 松溪县| 克拉玛依市| 武冈市| 沂源县| 伊春市| 西盟| 新建县| 富民县| 五常市| 利川市| 德格县| 甘肃省| 中西区| 甘孜县| 济阳县| 无极县| 抚宁县| 桂东县| 台北县| 茶陵县| 越西县| 华亭县|