android显示绘图动画,Android自定义View绘图实现渐隐动画
實現(xiàn)了一個有趣的小東西:使用自定義view繪圖,一邊畫線,畫出的線條漸漸變淡,直到消失。效果如下圖所示:
用屬性動畫或者漸變填充(shader)可以做到一筆一筆的變化,但要想一筆漸變(手指不抬起邊畫邊漸隱),沒在android中找到現(xiàn)成的api可用。所以,自己做了一個。
基本的想法是這樣的:
?在view的ontouchevent中記錄觸摸點,生成一條一條的線lineelement,放在一個list中。給每個lineelement配置一個paint實例。
?在ondraw中繪制線段。
?變換lineelement的paint實例的alpha值。
?根據(jù)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);
}
}
這個示例還可以添加一些效果,比如讓線條一邊變淡一邊變細。
目前還有一些問題,線條粗的話,可以明顯看到線段與線段之間有縫隙或裂口,哪位想到怎么優(yōu)化?
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持萬仟網(wǎng)。
總結(jié)
以上是生活随笔為你收集整理的android显示绘图动画,Android自定义View绘图实现渐隐动画的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: android状态机是线程么,Java中
 - 下一篇: 电脑耳机触电(电脑耳机电耳朵)