国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義View繪圖實現漸隱動畫

2019-12-12 05:21:36
字體:
來源:轉載
供稿:網友

實現了一個有趣的小東西:使用自定義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<LineElement> 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<LineElement>() ;    }    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);  }}
 

這個示例還可以添加一些效果,比如讓線條一邊變淡一邊變細。

目前還有一些問題,線條粗的話,可以明顯看到線段與線段之間有縫隙或裂口,哪位想到怎么優化?

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新龙县| 平阴县| 宝山区| 饶河县| 抚顺县| 饶平县| 杨浦区| 佳木斯市| 吉木萨尔县| 定州市| 霍州市| 故城县| 静海县| 巴彦淖尔市| 资溪县| 岳西县| 霍州市| 蕉岭县| 南京市| 滁州市| 麻城市| 泉州市| 旬邑县| 溧阳市| 邵武市| 泗水县| 公安县| 安宁市| 革吉县| 乌恰县| 甘德县| 神池县| 靖州| 吐鲁番市| 汾阳市| 淮滨县| 蓝田县| 芮城县| 财经| 正蓝旗| 漳平市|