欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2017年03月23日 09:10:29   作者:罔少年  
這篇文章主要為大家詳細(xì)介紹了Android自定義View葉子旋轉(zhuǎn)完整版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

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

2、添加滑動(dòng)條效果,顯示百分比

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

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());
 }

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

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

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

2、添加滑動(dòng)效果

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

a、定義一個(gè)圓形Rectf(為什么不是半圓?因?yàn)楫?huà)圓弧的其實(shí)角度從水平線右側(cè)開(kāi)始)

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

b、定義一個(gè)長(zhǎng)方形Rectf,長(zhǎng)方形x坐標(biāo)起點(diǎn)即時(shí)圓形半徑

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

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

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

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

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

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

給LeafView.java添加一個(gè)

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

 }

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

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

賦上所有代碼

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;
 //整個(gè)控件的寬度和高度
 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)度條實(shí)時(shí)背景
 private Paint progressBgPaint;
 //進(jìn)度條左側(cè)半圓,進(jìn)度條中間長(zhǎng)方形部分Rect
 private RectF progressArcRectf, progressRectf;
 //當(dāng)前百分比0~100
 private int currentProgress = 0;
 //存放葉子lsit
 private List<Leaf> leafList;
 //葉子的寬和高
 private int mLeafWidth, mLeafHeight;
 //葉子滑動(dòng)一周的時(shí)間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)度條實(shí)時(shí)背景
  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);
  //畫(huà)背景顏色到畫(huà)布
  canvas.drawRect(bgRect, bgPaint);
  if(currentProgress <= 100) {
   //畫(huà)葉子
   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è)置滑動(dòng)
    matrix.postTranslate(leaf.x, leaf.y);
    //設(shè)置旋轉(zhuǎn)
    matrix.postRotate(leaf.rotateAngle, leaf.x + mLeafWidth / 2, leaf.y + mLeafHeight / 2);
    //添加葉子到畫(huà)布
    canvas.drawBitmap(mLeafBitmap, matrix, new Paint());
    canvas.restore();

    //畫(huà)滑動(dòng)后的背景條
    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;
     // 掃過(guò)的角度
     int sweepAngle = 2 * angle;
     canvas.drawArc(progressArcRectf, startAngle, sweepAngle, false, progressBgPaint);
    }else {
     //畫(huà)左邊半圓形滑過(guò)部分
     canvas.drawArc(progressArcRectf, 90, 180, false, progressBgPaint);
     progressRectf.left = borderWidth + leftCircleWidth/2;
     progressRectf.right = borderWidth + currentProgressWidht;
     //畫(huà)中間滑過(guò)部分
     canvas.drawRect(progressRectf, progressBgPaint);
    }
   }

   //調(diào)用onDraw()重復(fù)滑動(dòng)
   if(currentProgress < 100) {
    postInvalidate();
   }
  }

  //畫(huà)背景圖片到畫(huà)布
  canvas.drawBitmap(bgBitmap, null, bgDestRect, null);
  //畫(huà)右邊選擇風(fēng)葉
  setTurnLeaf(canvas);
  //畫(huà)百分比
  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%開(kāi)始顯示,到50%停止滑動(dòng)
 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軸上的滑動(dòng)值
 private void getLocation(Leaf leaf) {
  float betweenTime = leaf.startTime - System.currentTimeMillis();
  //周期結(jié)束再加一個(gè)cycleTime
  if(betweenTime < 0) {
   leaf.startTime = System.currentTimeMillis() + cycleTime + new Random().nextInt((int) (cycleTime));
   betweenTime = cycleTime;
  }

  //通過(guò)時(shí)間差計(jì)算出葉子的坐標(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;
  // 起始時(shí)間(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;
 }

 //使葉子初始時(shí)間有間隔
 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.java

public 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é)

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

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

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

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

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

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論