首页 > 系统 > Android > 正文

Android自定义View实现多片叶子旋转滑动(五)

2019-12-12 03:18:24
字体:
来源:转载
供稿:网友

上一篇《Android 自定义View(四) 叶子飘动+旋转效果》实现了单片叶子的滑动及旋转,下面实现多片叶子的滑动旋转功能

实现思路比较简单,就是添加一个叶子Leaf类,储存每片叶子的信息,

然后随机产生叶子的坐标及旋转角度,最后实时获取每片叶子信息,添加到画布中

1、Leaf.java 叶子类

 private class Leaf {  // 叶子的坐标  float x, y;  // 旋转角度  int rotateAngle;  // 起始时间(ms)  long startTime; }

2、初始化每片叶子的信息,然后保存到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; } private List<Leaf> getLeafs(int leafSize) {  List<Leaf> list = new LinkedList<Leaf>();  for (int i=0; i<leafSize; i++) {   list.add(getLeaf());  }  return list; }

3、接下去就是改写getLocation()及getRotate()方法,使其返回每片叶子的坐标及旋转角度

 //获取每片叶子在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;  float w = (float) ((float) 2 * Math.PI / width);  int y = (int) (18 * Math.sin(w * x)) + (height-mLeafHeight)/2;  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; }

4、在onDraw()方法中,画出每片叶子

 @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  //画叶子  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();  }  //调用onDraw()重复滑动  postInvalidate(); }

完整代码:

public class LeafView extends View { private String TAG = "--------LeafView"; private Resources mResources; //背景图、叶子 private Bitmap mLeafBitmap, bgBitmap; //整个控件的宽度和高度 private int width, height; private Paint bgPaint; private RectF bgRect; private Rect bgDestRect; //存放叶子lsit private List<Leaf> leafList; //叶子的宽和高 private int mLeafWidth, mLeafHeight; //叶子滑动一周的时间5秒 private final static long cycleTime = 5000; //叶子数量 private final static int leafNumber = 5; 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()  bgBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.leaf_kuang, null)).getBitmap();  bgPaint = new Paint();  bgPaint.setColor(mResources.getColor(R.color.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;  bgDestRect = new Rect(0, 0 , width, height); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  bgRect = new RectF(0, 0 , width, height);  //画背景颜色到画布  canvas.drawRect(bgRect, bgPaint);  //画背景图片到画布  canvas.drawBitmap(bgBitmap, null, bgDestRect, null);  //画叶子  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();  }  //调用onDraw()重复滑动  postInvalidate(); } //获取每片叶子在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;  float w = (float) ((float) 2 * Math.PI / width);  int y = (int) (18 * Math.sin(w * x)) + (height-mLeafHeight)/2;  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; }}

这里还有很多瑕疵,比如叶子的滑动范围覆盖了边框等等

需要图片等信息的可以从下面的Github地址下载,不过原文比较复杂

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表