一个简单的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、大图加载图片压缩。

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

(0)

相关推荐

  • Android自定义视图实现手指移动轨迹

    今天看了大神写的关于贝塞尔曲线的博客,就写下了关于手指轨迹的一篇博客, 一.什么是贝塞尔曲线 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的.贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等. 二.贝塞尔曲线公式 三.手

  • android绘制触点轨迹的代码

    本文实例为大家分享了android绘制触点轨迹的具体代码,供大家参考,具体内容如下 重点函数是onTouchEvent(),所有的触摸事件都会在View的这个函数里面处理 单点触控 单点触控的event是通过event.getAction()获得的,一般最少需要考虑下面这三种情况 MotionEvent.ACTION_DOWN: 手指 初次接触到屏幕 时触发. MotionEvent.ACTION_MOVE: 手指 在屏幕上滑动 时触发,会多次触发. MotionEvent.ACTION_UP:

  • Android 利用三阶贝塞尔曲线绘制运动轨迹的示例

    本篇文章主要介绍了Android 利用三阶贝塞尔曲线绘制运动轨迹的示例,分享给大家,具体如下: 实现点赞效果,自定义起始点以及运动轨迹 效果图: xml布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/rl_root&

  • Android 游戏开发中绘制游戏触摸轨迹的曲线图

    本篇文章主要来讲解怎样绘制游戏触摸轨迹的曲线图. 我们在onTouchEvent方法中,可以获取到触摸屏幕时手指触摸点的x.y坐标,如何用这些点形成一条无规则轨迹并把这条无规则轨迹曲线显示在屏幕上就是本篇文章的主旨内容. Android Path类 Android提供了一个Path类 , 顾名思义这个类可以设置曲线路径轨迹.任何无规则的曲线实际上都是由若干条线段组成,而线段的定义为两点之间最短的一条线.path类就 可以记录这两点之间的轨迹,那么若干个Path 就是我们须要绘制的无规则曲线. 下

  • Android贝塞尔曲线实现手指轨迹

    本文实例为大家分享了Android贝塞尔曲线实现手指轨迹的具体代码,供大家参考,具体内容如下 1.使用贝塞尔曲线前 MyView.java public class MyView extends View { // 实例一个路径对象 private Path mPath = new Path(); public MyView(Context context) { super(context); // TODO Auto-generated constructor stub } public My

  • Android自定义view实现车载可调整轨迹线

    本文实例为大家分享了Android自定义view完成车载可调整轨迹线的具体代码,供大家参考,具体内容如下 同事做的view,拿过来做个记录. /** * */ package com.text.myviewdemo.view; import org.apache.http.conn.routing.RouteInfo.LayerType; import android.content.Context; import android.graphics.Canvas; import android.

  • 解决Android SurfaceView绘制触摸轨迹闪烁问题的方法

    本文分享了解决SurfaceView触摸轨迹闪烁问题的方法,供大家参考,具体内容如下 第一种解决SurfaceView触摸轨迹闪烁问题的方法: 由于SurfaceView使用双缓存机制,两张画布轮流显示到屏幕上.那么,要存储触摸轨迹并避免两张画布内容不一致造成的闪烁问题,完全可以利用保存绘制过程并不断重新绘制的方法解决闪烁,而且这样还顺带解决了多次试验中偶尔出现的因为moveTo()函数不能读取到参数执行默认设置(参数设为上次的触摸点)而出现的断线连接闪烁问题,详细代码如下: package c

  • Android中SurfaceView和view画出触摸轨迹

    一.引言          想实现一个空白的画板,上面可以画出手滑动的轨迹,就这么一个小需求.一般就来讲就两种实现方式,view或者surfaceview.下面看看两种是如何实现的. 二.实现原理          先简单说一下实现原理:        (1)用一张白色的Bitmap作为画板        (2)用canvas在bitmap上画线        (3)为了画出平滑的曲线,要用canvas的drawPath(Path,Paint)方法.        (4)同时使用贝塞尔曲线来使曲

  • Android自定义View实现公交成轨迹图

    本文实例为大家分享了Android自定义View实现公交成轨迹图的具体代码,供大家参考,具体内容如下 总体分析下:水平方向recyclewview,item包含定位点,站台位置和站台名称. 下面看实现: 1.继承framelayout,实现构造方法: public class BusStopPlateView extends FrameLayout { ... public BusStopPlateView(@NonNull Context context) { super(context);

  • Android贝塞尔曲线初步学习第三课 Android实现添加至购物车的运动轨迹

    不知上一节高仿QQ未读消息气泡大家还喜欢么,今天继续练习贝赛尔曲线,这一节我们通过贝赛尔曲线和属性动画估值器实现添加至购物车的运动轨迹,效果如下: 1.新建自定义View,重写构造方法,初始化Paint.Path: 2.确定起始点.终止点.控制点坐标,这里我们直接固定: @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh);

  • Android轻松画出触摸轨迹

    本文实例介绍了Android如何画出触摸轨迹的方法,分享给大家供大家参考,具体内容如下 效果图: 实现代码: package com.android.gameview5; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import an

随机推荐