欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-11-28 15:53:40
上一篇《android 自定义view(四) 叶子飘动+旋转效果》实现了单片叶子的滑动及旋转,下面实现多片叶子的滑动旋转功能 实现思路比较简单,就是添加一个叶子lea...

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

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

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