android仿百度福袋红包界面

  public class LYJGestureView extends android.view.View {

  /***

  * 声明直线画笔

  */

  private Paint paint;

  /***

  * 声明圆圈画笔

  */

  private Paint circlePaint;

  /***

  * 画布

  */

  private Canvas canvas;

  /***

  * 位图

  */

  private Bitmap bitmap;

  /***

  * 装有各个view坐标的集合,用于判断点是否在其中

  */

  private List list;

  /***

  * 记录画过的线

  */

  private List> lineList;

  /***

  * 记录画过的圆

  */

  private List circlePoints;

  /**

  * 手指当前在哪个Point内

  */

  private LYJGesturePoint currentPoint;

  /***

  * 手指按下动画

  */

  private OnAnimationCallback animationCallback;

  public interface OnAnimationCallback{

  public void startAnimationImage(int i);

  }

  public void setAnimationCallback(OnAnimationCallback animationCallback) {

  this.animationCallback = animationCallback;

  }

  public LYJGestureView(Context context, List list){

  super(context);

  Log.i(getClass().getName(), "GestureDrawline");

  paint = new Paint(Paint.DITHER_FLAG);// 创建一个画笔

  circlePaint=new Paint(Paint.DITHER_FLAG);

  DisplayMetrics metric = new DisplayMetrics();

  ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(metric);

  Log.i(getClass().getName(), "widthPixels" + metric.widthPixels);

  Log.i(getClass().getName(), "heightPixels" + metric.heightPixels);

  bitmap = Bitmap.createBitmap(metric.widthPixels, metric.heightPixels, Bitmap.Config.ARGB_8888); // 设置位图的宽高

  canvas = new Canvas();

  canvas.setBitmap(bitmap);

  paint.setStyle(Paint.Style.STROKE);// 设置非填充

  paint.setStrokeWidth(20);// 笔宽20像素

  paint.setColor(Color.rgb(245, 142, 33));// 设置默认连线颜色

  paint.setAntiAlias(true);// 不显示锯齿

  circlePaint.setStyle(Paint.Style.FILL);

  circlePaint.setStrokeWidth(1);

  circlePaint.setAntiAlias(true);

  circlePaint.setColor(Color.rgb(245, 142, 33));

  this.list = list;

  this.lineList = new ArrayList<>();

  this.circlePoints=new ArrayList<>();

  }

  @Override

  public boolean onTouchEvent(MotionEvent event) {

  switch (event.getAction()){

  case MotionEvent.ACTION_DOWN:

  // 判断当前点击的位置是处于哪个点之内

  currentPoint = getPointAt((int) event.getX(), (int) event.getY());

  if (currentPoint != null) {

  currentPoint.setPointState(Constants.POINT_STATE_SELECTED);

  this.animationCallback.startAnimationImage(currentPoint.getNum());

  canvas.drawCircle(currentPoint.getCenterX(), currentPoint.getCenterY(), 20, circlePaint);

  circlePoints.add(new LYJCirclePoint(currentPoint.getCenterX(),currentPoint.getCenterY(),20));

  }

  invalidate();

  break;

  case MotionEvent.ACTION_MOVE:

  clearScreenAndDrawList();

  // 得到当前移动位置是处于哪个点内

  LYJGesturePoint pointAt = getPointAt((int) event.getX(), (int) event.getY());

  if (currentPoint == null && pointAt == null) {//你把手指按在屏幕滑动,如果终点与起点都不图片那么返回

  return true;

  } else {// 代表用户的手指移动到了点上

  if (currentPoint == null) {// 先判断当前的point是不是为null

  // 如果为空,那么把手指移动到的点赋值给currentPoint

  currentPoint = pointAt;

  // 把currentPoint这个点设置选中状态;

  currentPoint.setPointState(Constants.POINT_STATE_SELECTED);

  }

  }

  //如果移动到的点不为图片区域或者移动到自己的地方,或者该图片已经为选中状态,直接画直线就可以了

  if(pointAt == null || currentPoint.equals(pointAt) || Constants.POINT_STATE_SELECTED == pointAt.getPointState()){

  canvas.drawCircle(currentPoint.getCenterX(), currentPoint.getCenterY(), 20, circlePaint);

  circlePoints.add(new LYJCirclePoint(currentPoint.getCenterX(), currentPoint.getCenterY(), 20));

  canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), event.getX(), event.getY(), paint);

  }else{//其他情况画两点相连直线,并且保存绘制圆与直线,并调用按下图片的缩放动画

  canvas.drawCircle(pointAt.getCenterX(),pointAt.getCenterY(),20,circlePaint);

  circlePoints.add(new LYJCirclePoint(pointAt.getCenterX(), pointAt.getCenterY(), 20));

  this.animationCallback.startAnimationImage(pointAt.getNum());

  pointAt.setPointState(Constants.POINT_STATE_SELECTED);

  canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), pointAt.getCenterX(), pointAt.getCenterY(), paint);

  Pair pair = new Pair<>(currentPoint, pointAt);

  lineList.add(pair);

  currentPoint=pointAt;//设置选中点为当前点。

  }

  invalidate();//重绘

  break;

  case MotionEvent.ACTION_UP:

  clearScreenAndDrawList();//防止多出一条没有终点的直线

  new Handler().postDelayed(new clearLineRunnable(), 1000);//1秒后清空绘制界面

  invalidate();//重绘

  break;

  default:

  break;

  }

  return true;

  }

  class clearLineRunnable implements Runnable {

  public void run() {

  // 清空保存点与圆的集合

  lineList.clear();

  circlePoints.clear();

  // 重新绘制界面

  clearScreenAndDrawList();

  for (LYJGesturePoint p : list) {

  //设置其为初始化不选中状态

  p.setPointState(Constants.POINT_STATE_NORMAL);

  }

  invalidate();

  }

  }

  /**

  * 通过点的位置去集合里面查找这个点是包含在哪个Point里面的

  *

  * @param x

  * @param y

  * @return 如果没有找到,则返回null,代表用户当前移动的地方属于点与点之间

  */

  private LYJGesturePoint getPointAt(int x, int y) {

  for (LYJGesturePoint point : list) {

  // 先判断点是否在图片的X坐标内

  int leftX = point.getPointLeftTop().x;

  int rightX = point.getPointRightBottom().x;

  if (!(x >= leftX && x < rightX)) {

  // 如果为假,则跳到下一个对比

  continue;

  }

  //在判断点是否在图片的Y坐标内

  int topY = point.getPointLeftTop().y;

  int bottomY = point.getPointRightBottom().y;

  if (!(y >= topY && y < bottomY)) {

  // 如果为假,则跳到下一个对比

  continue;

  }

  // 如果执行到这,那么说明当前点击的点的位置在遍历到点的位置这个地方

  return point;

  }

  return null;

  }

  /**

  * 清掉屏幕上所有的线,然后画出集合里面的线

  */

  private void clearScreenAndDrawList() {

  canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

  for (Pair pair : lineList) {

  canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(),

  pair.second.getCenterX(), pair.second.getCenterY(), paint);// 画线

  }

  for(LYJCirclePoint lyjCirclePoint : circlePoints){

  canvas.drawCircle(lyjCirclePoint.getRoundX(),lyjCirclePoint.getRoundY(), lyjCirclePoint.getRadiu(),circlePaint);

  }

  }

  //绘制用bitmap创建出来的画布

  @Override

  protected void onDraw(Canvas canvas) {

  canvas.drawBitmap(bitmap, 0, 0, null);

  }

  }