一个简单的Android轨迹动画
本文实例为大家分享了Android轨迹动画的具体代码,供大家参考,具体内容如下
二、需求描述
年中那会儿基友的公司给他了一张只有一条曲线的图,想让他按照曲线的轨迹动态展示整个曲线,然而基友忙于把妹,一个馒头的代价收买了我,于是帮他写了代码。先看下实现效果
上原始图(原始图的轨迹曲线是白色的,其他部分是透明的,这里为了便于观察,我将背景调为黑色)
三、分析实现
讲道理,刚拿到这个图片的时候我也有点懵逼,一个毫无规律的曲线很显然不能通过简单的方程式去描述点的具体位置,甚至想说设计直接给个动画岂不美滋滋......
吐槽归吐槽,需求还是要实现的,而且这个需求是有不少常见的方法可以进行实现的,比如上下两层图片保持一直,上层不断从左到右将原图纵向像素清除,然后将设计给的图片也按照从左到友的顺去绘制上去。不过这种方法的可扩展性太差,底层的图片发生改变(滑动、变色)上层也需要进行配合。
这里使用方法是:将图片中有色像素在图片上的位置按照比例映射到要绘制的View中。
比如,原图大小是200*100,要去做展示的View的尺寸大小是450*300,某点在原图中位于x100,y20的位置,那么它在view中的位置应该为225,60。也就是说将该点在途中的位置比上原图对应尺寸然后在乘以View的尺寸即可。
轨迹的获取可以通过获取全部的像素点颜色,因为透明的必然不是轨迹,所以判断Alpha值即可,又因为轨迹是一条线,当我们使用Path连点的时候为了尽量减少不必要点的连接,我这里通过平均值的方式将曲线的宽度降为1。
由于点的位置是按照尺寸比例计算的,所以无论要展示的图片尺寸有多奇葩,都可以完美适配上去
四、实现代码
public class TestView extends View implements ViewTreeObserver.OnGlobalLayoutListener{ private Paint paint = new Paint(); private Bitmap bitmap; private int[]local; boolean enter = false; int count; ViewTreeObserver observer; Canvas canvas; float lastX = 0; float lastY = 0; public TestView(Context context) { super(context); } public TestView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); observer = this.getViewTreeObserver(); observer.addOnGlobalLayoutListener(this); getImageFromAssetsFile("target.png");//读取图片 } public TestView(Context context, AttributeSet attrs) { super(context, attrs); observer = this.getViewTreeObserver(); observer.addOnGlobalLayoutListener(this); getImageFromAssetsFile("target.png"); } private void getImageFromAssetsFile(String fileName) { AssetManager am = getResources().getAssets(); try { InputStream is = am.open(fileName); bitmap = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); } } private void filterColor(){ int w = bitmap.getWidth(); int h = bitmap.getHeight(); int[]pixels = new int[w*h]; local = new int[w];//以原图宽为单位,保存点在原图Y轴上的位置 bitmap.getPixels(pixels,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight()); for(int i = 0; i < w; i++){ int lenght = 0; int total = 0; for(int j = 0;j<h;j++){ if (bitmap.getPixel(i, j) !=0) { lenght++; total+=j; } } System.out.println(lenght+""); if(lenght<15||((float)i/(float) w)<0.85) local[i] = total/lenght; else break; } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(enter) { paint.setAntiAlias(true); //设置画笔为无锯齿 paint.setColor(Color.WHITE); //设置画笔颜色 canvas.drawColor(Color.TRANSPARENT); //透明背景 paint.setStrokeWidth((float) 6.0); //线宽 paint.setStyle(Paint.Style.STROKE); Path path = new Path(); path.moveTo(0, (((float) getMeasuredHeight()-25) / (float)bitmap.getHeight()) * (float) local[0]+7); if (count <= bitmap.getWidth()) { if(count<bitmap.getWidth()) count++; for (int i = 1; i < count - 1; i++) { if(local[i]>0) { path.lineTo((getMeasuredWidth() / (float) bitmap.getWidth()) * (float) i, (((float) getMeasuredHeight()-25) / (float) bitmap.getHeight()) * (float) local[i]+7); lastX = (getMeasuredWidth() / (float) bitmap.getWidth()) * (float) i; lastY = (((float) getMeasuredHeight()-25 )/ (float) bitmap.getHeight()) * (float) local[i]; } } } if(count<bitmap.getWidth()) postInvalidate(); else { count = 0; postInvalidate(); } canvas.drawPath(path, paint); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(lastX, lastY+7, 7, paint); // } }else{ this.canvas = canvas; } } @Override public void onGlobalLayout() { filterColor(); enter = true; postInvalidate(); } }
当然了,这个代码也只是给基友交差用的,还有不少地方能做优化,比如:将图片读取放在子线程、对图片大小进行判断避免OOM、大图加载图片压缩。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
栏 目:Android
下一篇:Android倒计时控件 Splash界面5秒自动跳转
本文标题:一个简单的Android轨迹动画
本文地址:https://www.xiuzhanwang.com/a1/Android/9174.html
您可能感兴趣的文章
- 01-10android实现简单计算器功能
- 01-10Android 友盟第三方登录与分享的实现代码
- 01-10Emoji表情在Android JNI中的兼容性问题详解
- 01-10android开发环境中SDK文件夹下的所需内容详解
- 01-10Android实现底部导航栏的主界面
- 01-10Android实现渐变启动页和带有指示器的引导页
- 01-10Android实现简单手电筒功能
- 01-10android特卖列表倒计时卡顿问题的解决方法
- 01-10Android倒计时的开始与停止 剩余时分秒的展示
- 01-10一个简单的Android圆弧刷新动画
阅读排行
本栏相关
- 01-10Android自定义View之绘制圆形头像功能
- 01-10Android实现双击返回键退出应用实现方
- 01-10android实现简单计算器功能
- 01-10android实现记住用户名和密码以及自动
- 01-10C++自定义API函数实现大数相乘算法
- 01-10Android 友盟第三方登录与分享的实现代
- 01-10android实现指纹识别功能
- 01-10如何给Flutter界面切换实现点特效
- 01-10Android实现圆形渐变加载进度条
- 01-10Emoji表情在Android JNI中的兼容性问题详
随机阅读
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 01-11ajax实现页面的局部加载
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文
- 04-02jquery与jsp,用jquery
- 01-10C#中split用法实例总结
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 01-10SublimeText编译C开发环境设置
- 08-05织梦dedecms什么时候用栏目交叉功能?
- 01-10delphi制作wav文件的方法