实现了一个有趣的小东西:使用自定义view绘图,一边画线,画出的线条渐渐变淡,直到消失。效果如下图所示:

用属性动画或者渐变填充(shader)可以做到一笔一笔的变化,但要想一笔渐变(手指不抬起边画边渐隐),没在android中找到现成的api可用。所以,自己做了一个。

基本的想法是这样的:

•在view的ontouchevent中记录触摸点,生成一条一条的线lineelement,放在一个list中。给每个lineelement配置一个paint实例。

•在ondraw中绘制线段。

•变换lineelement的paint实例的alpha值。

•根据alpha值重组线段列表

别的不说了,上代码:

package com.example.disappearinglines;

import android.content.context;

import android.graphics.canvas;

import android.graphics.paint;

import android.graphics.path;

import android.graphics.rectf;

import android.os.handler;

import android.os.message;

import android.os.systemclock;

import android.support.annotation.nonnull;

import android.util.attributeset;

import android.util.log;

import android.view.motionevent;

import android.view.view;

import java.util.arraylist;

import java.util.collection;

import java.util.iterator;

import java.util.list;

import java.util.listiterator;

public class disappearingdoodleview extends view {

final static string tag = "doodleview";

class lineelement {

static final public int alpha_step = 5;

static final public int subpath_dimension = 8;

public lineelement(){

mpaint = new paint();

mpaint.setargb(255, 255, 0, 0);

mpaint.setantialias(true);

mpaint.setstrokewidth(16);

mpaint.setstrokecap(paint.cap.butt);

mpaint.setstyle(paint.style.stroke);

}

public lineelement(paint paint){

mpaint = paint;

}

public void setpaint(paint paint){

mpaint = paint;

}

public void setalpha(int alpha){

mpaint.setalpha(alpha);

}

public float mstartx = -1;

public float mstarty = -1;

public float mendx = -1;

public float mendy = -1;

public paint mpaint;

}

private lineelement mcurrentline = null;

private list mlines = null;

private long melapsed = 0;

private handler mhandler = new handler(){

@override

public void handlemessage(message msg){

disappearingdoodleview.this.invalidate();

}

};

public disappearingdoodleview(context context){

super(context);

}

public disappearingdoodleview(context context, attributeset attrs){

super(context, attrs);

}

@override

protected void ondraw(canvas canvas){

melapsed = systemclock.elapsedrealtime();

if(mlines != null) {

for (lineelement e : mlines) {

if(e.mstartx < 0 || e.mendy < 0) continue;

canvas.drawline(e.mstartx, e.mstarty, e.mendx, e.mendy, e.mpaint);

}

compactpaths();

}

}

@override

public boolean ontouchevent(motionevent event){

float x = event.getx();

float y = event.gety();

int action = event.getaction();

if(action == motionevent.action_up){// end one line after finger release

mcurrentline.mendx = x;

mcurrentline.mendy = y;

mcurrentline = null;

invalidate();

return true;

}

if(action == motionevent.action_down){

mcurrentline = new lineelement();

addtopaths(mcurrentline);

mcurrentline.mstartx = x;

mcurrentline.mstarty = y;

return true;

}

if(action == motionevent.action_move) {

mcurrentline.mendx = x;

mcurrentline.mendy = y;

mcurrentline = new lineelement();

addtopaths(mcurrentline);

mcurrentline.mstartx = x;

mcurrentline.mstarty = y;

}

if(mhandler.hasmessages(1)){

mhandler.removemessages(1);

}

message msg = new message();

msg.what = 1;

mhandler.sendmessagedelayed(msg, 0);

return true;

}

private void addtopaths(lineelement element){

if(mlines == null) {

mlines = new arraylist() ;

}

mlines.add(element);

}

public void compactpaths(){

int size = mlines.size();

int index = size - 1;

if(size == 0) return;

int basealpha = 255 - lineelement.alpha_step;

int itselfalpha;

lineelement line;

for(; index >=0 ; index--, basealpha -= lineelement.alpha_step){

line = mlines.get(index);

itselfalpha = line.mpaint.getalpha();

if(itselfalpha == 255){

if(basealpha <= 0){

++index;

break;

}

line.setalpha(basealpha);

}else{

itselfalpha -= lineelement.alpha_step;

if(itselfalpha <= 0){

++index;

break;

}

line.setalpha(itselfalpha);

}

}

if(index >= size){

// all sub-path should disappear

mlines = null;

}

else if(index >= 0){

//log.i(tag, "compactpaths from " + index + " to " + (size - 1));

mlines = mlines.sublist(index, size);

}else{

// no sub-path should disappear

}

long interval = 40 - systemclock.elapsedrealtime() + melapsed;

if(interval < 0) interval = 0;

message msg = new message();

msg.what = 1;

mhandler.sendmessagedelayed(msg, interval);

}

}

这个示例还可以添加一些效果,比如让线条一边变淡一边变细。

目前还有一些问题,线条粗的话,可以明显看到线段与线段之间有缝隙或裂口,哪位想到怎么优化?

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

android显示绘图动画,Android自定义View绘图实现渐隐动画相关推荐

  1. android卡包动画,自定义View实现银行卡卡包动画效果

    本来不想自己造轮子的,但奈何没找动相应效果的轮子,所以只能自己写了,其实还是白嫖来的轻松,哈哈 先看效果 这个是完成的效果,还可以吧!关键也不难一个自定义View搞定 先说一下思路,继承一个Relat ...

  2. 用c语言绘制自定义图形,Android使用自定义View绘图

    使用自定义 View 绘图 实例 MyViewCanvasDemo 自定义一个名为 MyView 的 View 类,并在其 onDraw() 方法中绘制简单的图像,运行效果如图 1 所示. 图 1   ...

  3. Android 雪花飘落动画效果 自定义View

    在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天.每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不 ...

  4. android 自定义 对号,Android自定义View实现打钩动画功能

    先上效果图 动图 静态图 1. 回顾 [Android自定义View:一个精致的打钩小动画]上一篇文章,我们已经实现了基本上实现了控件的效果了,但是...但是...过了三四天后,仔细看回自己写的代码, ...

  5. Android属性动画与自定义View——实现vivo x6更新系统的动画效果

    晚上好,现在是凌晨两点半,然后我还在写代码.电脑里播放着<凌晨两点半>,晚上写代码,脑子更清醒,思路更清晰. 今天聊聊属性动画和自定义View搭配使用,前面都讲到自定义View和属性动画, ...

  6. Android 气泡动画(自定义View类)

    Android 气泡动画(自定义View类) 一.前言 二.代码 1. 随机移动的气泡 2.热水气泡 一.前言 最近有需求制作一个水壶的气泡动画,首先在网上查找了一番,找到了一个文章. https:/ ...

  7. 自定义view绘图篇--图片和文字的绘制

    图片的绘制功能可以让我们直接添加一张图片到画布,文字的绘制可以点缀我们view的功能.本章节继续深入,总结下其中的流程. 知识点 一.绘制图片 1.Picture类 (1)Picture类的功能 我们 ...

  8. Android显示九宫图(自定义圆角,仿微信九宫格图)

    详细解析Android显示九宫图(自定义圆角,仿微信九宫格图) 这是一个自定义九宫格图片框架,里面有设置圆角大小,还有当图片一张的时候控件自定义的大小,图片的间隔,四张图片的时候图片自定义为两行两列等 ...

  9. Android中实现Bitmap在自定义View中的放大与拖动

    一基本实现思路: 基于View类实现自定义View –MyImageView类.在使用View的Activity类中完成OnTouchListener接口,实现对MotionEvent事件的监听与处理 ...

最新文章

  1. github创建本地库后关联远程库
  2. ul弹性怎么一行显示_css3系列之弹性盒子 flex
  3. java小数强制转换,Java中的强制类型转换 大数转小数
  4. Qt 程序获取程序所在路径、用户目录路径、临时文件夹等特殊路径的方法
  5. 使用Ext.grid.Panel生成表格
  6. 拜托!你真会用线程池吗?
  7. 计算机应用在服务业的发展,饮食服务业计算机应用的现状与未来
  8. C++ Primer Message和Folder类
  9. 利用GSensor让屏幕实现360度旋转
  10. adb常用的命令【杭州多测师_王sir】【杭州多测师】
  11. 记录一下uni-app开发中遇到的坑
  12. 数据、数据元素、数据项、数据对象的理解
  13. dx12 龙书第四章学习笔记 -- Direct3D的初始化
  14. java图片转视频,附加代码以供参考
  15. 12864液晶屏调试笔记.
  16. 【Halcon】模板匹配算子
  17. 初次使用CardView设置圆角等属性出现的问题(设置圆角出现层叠,外层View多出角的问题)
  18. 《Qt图形界面编程入门》课后习题全解
  19. 学Android看这就完事了!2021年最新Android面试精讲,赶紧收藏!
  20. Python:numpy 矩阵除以向量

热门文章

  1. cdh搭建hadoop集群_Hadoop宿醉:使用Apache Whirr启动hadoop集群CDH4
  2. zip和unzip上的Java要点
  3. 投资银行对Java进行的二十大核心面试问答
  4. 但这是不可能的,或者无法发现JIT破坏了您的代码。
  5. JavaFX技巧7:使用CSS颜色常量/派生颜色
  6. JavaFX技巧6:使用透明颜色
  7. Spring Data Couchbase 1.0 GA发布
  8. JMS和Spring:有时很重要的小事情
  9. Drools Planner重命名为OptaPlanner:宣布www.optaplanner.org
  10. Java 7 –反编译项目硬币