Android自定义View实现多片叶子旋转滑动(五)
程序员文章站
2023-11-28 15:53:40
上一篇《android 自定义view(四) 叶子飘动+旋转效果》实现了单片叶子的滑动及旋转,下面实现多片叶子的滑动旋转功能
实现思路比较简单,就是添加一个叶子lea...
上一篇《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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Android仿探探卡片式滑动效果实现