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

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

d7b38b8a19a75b794a20139ad4b54754.gif

用属性动画或者渐变填充(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);

}

}

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/339187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python网络编程项目_python网络编程详解

最近在看《UNIX网络编程 卷1》和《FREEBSD操作系统设计与实现》这两本书&#xff0c;我重点关注了TCP协议相关的内容&#xff0c;结合自己后台开发的经验&#xff0c;写下这篇文章&#xff0c;一方面是为了帮助有需要的人&#xff0c;更重要的是方便自己整理思路&#xff0c;加…

分享10个值得关注的C语言开源项目

来源于网络&#xff0c;如有侵权&#xff0c;告知必删。

python3 x默认使用的编码_python3默认使用什么编码

python3默认编码为unicode&#xff0c;由str类型进行表示。二进制数据使用byte类型表示。 字符串通过编码转换成字节码&#xff0c;字节码通过解码成为字符串encode&#xff1a;str --> bytes&#xff08;推荐学习&#xff1a;Python视频教程&#xff09; decode&#xff1a…

html中写css代码,开发DIV CSS时 先写CSS代码还是先写HTML代码

相信良多&#xff2c;&#xff2f;&#xff36;&#xff25;用DIVCSS技术启示重构网页的爱好者友好&#xff0c;在起源学习DIVCSS的时分都邑想一个标题&#xff0c;想晓得DIVCSS妙手或有教育者在开发制作html页面的时刻&#xff0c;下场是先写html照样先写css&#xff1f;带着这…

象棋子 设计模式_通过设计国际象棋游戏了解策略模式

象棋子 设计模式今天&#xff0c;我们将借助一个示例来尝试了解策略模式。 我们将考虑的示例是国际象棋游戏。 这里的目的是解释策略模式&#xff0c;而不是构建全面的国际象棋游戏解决方案。 策略模式&#xff1a;策略模式被称为行为模式–用于管理对象之间的算法&#xff0…

入门C语言10问10答

1 如何理解变量与常量?变量与常量相当于数据的可读可写与只读&#xff0c;常量是数据的一种保护机制。在内存分配给程序的内存块中有专门的常量&#xff08;只读&#xff09;存储区。2 整型数据的溢出问题任何一种数据类型的数据在计算机中都有它确定的数值表示范围&#xff0…

mac json格式化工具_简洁好用的工具都是相似的

大家好&#xff0c;我是你们的章鱼猫。不知道大家了不了解 jq 这个工具呢&#xff1f;指的不是 JQuery&#xff0c;而是一个命令行工具。jq 是一个轻量级而且灵活的命令行 JSON 解析器&#xff0c;类似用于 JSON 数据的 sed 工具。我们来看一下使用 jq 处理 json 的基本用法(更…

战神4 幕后花絮 概念艺术_Java 9幕后花絮:新功能从何而来?

战神4 幕后花絮 概念艺术找出Java幕后发生的事情&#xff0c;以及新功能如何实现 在上一篇文章中&#xff0c;我们介绍了即将发布的Java 9版本的新功能和尚待解决的功能&#xff0c;并简要提到了将新功能添加到下一个版本之前要经历的过程。 由于此过程几乎影响了所有Java开发人…

ID生成器 雪花算法

背景&#xff1a;在很多业务场景下&#xff0c;我们都需要一个唯一的 ID 来进行一些数据的交互&#xff0c;那么如何生成这个唯一的 ID 呢&#xff1f;如果在单机的情况下&#xff0c;生成唯一ID&#xff0c;可以利用机器内存的特点&#xff0c;通过内存分配即可。但我们线上的…

python anaconda安装_Python - 安装并配置Anaconda环境

$ py --version # 当前默认python版本 Python 3.7.1 $ conda create --name testpy2 python2.7 pandas # 创建名为testpy2的运行环境&#xff0c;并安装pandas包及其依赖包 Solving environment: done ## Package Plan ## environment location: D:\DownLoadFiles\anaconda3\en…

jstack调试_增压的jstack:如何以100mph的速度调试服务器

jstack调试使用jstack调试实时Java生产服务器的指南 jstack就像U2一样-从时间的黎明就一直在我们身边&#xff0c;我们似乎无法摆脱它 。 除了笑话&#xff0c;到目前为止&#xff0c;jstack是您的工具库中用于调试实时生产服务器的最方便的工具之一。 即便如此&#xff0c;我仍…

C/C 输入输出缓冲区

【导读】&#xff1a;本文介绍C与C 输入输出缓冲的一些操作与特性。以下是正文&#xff08;1&#xff09;c 中cin、cout&#xff0c;cerr和c的stdin、stdout、stderr都是同步的&#xff0c;即iostream 对象和 and cstdio流是同步的&#xff0c;同步关系如下&#xff1a;同步即表…

python输入input数组_python怎么输入数组

python怎么输入数组&#xff1f; python输入数组 一维数组&#xff1a;arr input("") //输入一个一维数组&#xff0c;每个数之间使空格隔开 num [int(n) for n in arr.split()] //将输入每个数以空格键隔开做成数组 print(num) //打印数组 一维数组输入输出示例&a…

eclipse 扩展_Eclipse扩展的轻量级集成测试

eclipse 扩展最近&#xff0c;我为Eclipse扩展点评估引入了一个小助手。 辅助程序努力减少通用编程步骤的样板代码&#xff0c;同时增加开发指导和可读性。 这篇文章是希望的后续文章&#xff0c;它显示了如何将实用程序与AssertJ定制断言结合使用&#xff0c;以编写针对Eclip…

深入理解右值引用,move语义和完美转发

move语义最原始的左值和右值定义可以追溯到C语言时代&#xff0c;左值是可以出现在赋值符的左边和右边&#xff0c;然而右值只能出现在赋值符的右边。在C 里&#xff0c;这种方法作为初步判断左值或右值还是可以的&#xff0c;但不只是那么准确了。你要说C 中的右值到底是什么&…

java future用法_纯干货:Java学习过程中的21个知识点和技术点

我们在Java学习过程中要学会抓重点&#xff0c;善于总结&#xff0c;Java学习过程中常见的21个知识点和技术点你知道吗&#xff1f;下面和千锋广州小编一起来看看吧&#xff01;1. JVM相关对于刚刚接触Java的人来说&#xff0c;JVM相关的知识不一定需要理解很深&#xff0c;对此…

如何优雅地检测类型/表达式有效性?

注1&#xff1a;本文至少需要编译器支持C 11。注2&#xff1a;本文不考虑使用宏。一、老办法在写C 的时候&#xff0c;有时候可能需要检查一个类是否有特定的成员类型&#xff0c;例如&#xff1a;// 检查 T::type 是否存在&#xff0c;存在则 value 为 true&#xff0c;否则为…

swagger api文档_带有Swagger的Spring Rest API –公开文档

swagger api文档创建API文档后&#xff0c;将其提供给涉众很重要。 在理想情况下&#xff0c;此发布的文档将足够灵活以解决任何最后的更改&#xff0c;并且易于分发&#xff08;就成本以及完成此操作所需的时间而言&#xff09;。 为了使之成为可能&#xff0c;我们将利用我在…

nuxt解决首屏加载慢问题_一个 Node 脚本让你的前端项目加载速度飞起来

写在最前面我的原创什么声明变成什么鬼了……前言随着前端三大框架的盛行&#xff0c;越来越多的前后端分离项目在服务器上跑了起来&#xff0c;随之而来&#xff0c;开发者也慢慢发现了这种开发模式所带来的弊端&#xff0c;其中之一就是首屏加载速度特别慢&#xff0c;因为虽…

数据库连接配置tomcat_Tomcat到Wildfly:配置数据库连接

数据库连接配置tomcat该摘录摘自《 从Tomcat到WildFly 》一书&#xff0c;您将在其中学习如何将现有的Tomcat体系结构移植到WildFly&#xff0c;包括服务器配置和在其顶部运行的应用程序。 WildFly是完全兼容的Java Enterprise Edition 7容器&#xff0c;与Tomcat相比&#xf…