`

QuadView贝塞尔View

阅读更多
不知从什么时候起,码农们都热衷于果冻、粘黏、水滴效果了,认为效果很酷很新奇
但是只是用而已,知道原理的并不多
本篇将实现一个最基本的效果(我也不知道该叫什么效果),见图



原理很简单,就是利用的了Path的quadTo方法,该函数用于绘制贝塞尔曲线

我懒得打字了,直接看代码:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * 贝塞尔View
 * 
 * @author pythoner
 */
public class QuadView extends View implements Runnable {
	private final String tag = "tag";
	private int SLEEP_TIME = 10;
	private boolean isRunning = false;
	private int detalY = 20;// 每循环一次拉下的幅度增量值
	private int maxY = 800;// 允许下拉的最大距离

	private Path path;
	private Paint paint;

	private int y = 0;
	private int w;// view的宽

	public QuadView(Context context) {
		super(context);
	}

	public QuadView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public QuadView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
	}

	public void init() {
		w = getWidth();
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(Color.RED);
		paint.setStrokeWidth(10);
		paint.setStyle(Paint.Style.FILL);

		path = new Path();
		setPath();

	}

	@Override
	public void onDraw(Canvas c) {
		super.onDraw(c);

		c.save();
		c.drawColor(Color.WHITE);
		c.drawPath(path, paint);
		c.restore();
	}

	private float oldY = 0;

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			if (isRunning) {// 线程正在运行的时候打断,把任务交给手势处理
				isRunning = false;
			}
			oldY = event.getY();
			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:
			float newY = event.getY();
			if (newY - oldY > 5) {// 向下拉
				if (y < maxY) {
					y += detalY;
				}
				setPath();
				invalidate();
			} else if (newY - oldY < -5) {// 向上拉
				y -= detalY;
				if (y < 0) {
					y = 0;
				}
				setPath();
				invalidate();
			}
			oldY = newY;
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			if (!isRunning) {// 线程正在运行的时候,不允许重复执行
				Thread t = new Thread(this);
				t.start();
			}
			break;

		default:
			break;
		}

		return true;
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
		// TODO Auto-generated method stub
		super.onLayout(changed, left, top, right, bottom);
		Log.i(tag, "=========onLayout===========");
		init();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		Log.i(tag, "=========onMeasure===========");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		isRunning = true;
		while (isRunning) {
			long start = System.currentTimeMillis();
			if (y > 0) {
				y -= detalY;
			} else {
				isRunning = false;
			}
			setPath();
			postInvalidate();// 相当于repaint
			long end = System.currentTimeMillis();
			if (end - start < SLEEP_TIME) {
				try {
					Thread.sleep(SLEEP_TIME - (end - start));
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	private void setPath() {
		path.reset();
		path.moveTo(0, 0);
		path.quadTo(w >> 1, y, w, 0);
	}
}


手指下拉,红色区域会呈水滴状出现,释放后又返回到初始状态。
  • 大小: 32.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics