2013-04-07 51 views
4

我想繪製圓,每當用戶點擊自定義視圖時,並基於點擊計數圓圈顏色更改。標識自定義視圖上的三次點擊

Single Tap : YELLOW CIRCLE 
Double Tap : GREEN CIRCLE 
Triple Tap : RED COLOR 

問題是,我做了一個自定義視圖,將根據時間計算自來水事件,但過一段時間就錯過了第一個水龍頭。這導致了問題。

以下代碼顯示了我在自定義視圖之上所做的所有努力。

TripleTapView

package com.slk.car_rating_app; 

import java.util.ArrayList; 
import java.util.Date; 

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PointF; 
import android.graphics.RectF; 
import android.os.CountDownTimer; 
import android.view.MotionEvent; 
import android.view.View; 

public class TripleTapView extends View { 
    // Set the tap delay in milliseconds 
    protected static final long TAP_MAX_DELAY = 500L; 
    // Radius to capture tap within bound 
    final static int RADIUS = 30; 
    // Store all points with tap count 
    public ArrayList<CustomPoint> point = new ArrayList<CustomPoint>(); 
    // Context to access view 
    Context context; 
    Paint paint; 
    private long thisTime = 0, prevTime = 0; 
    private boolean firstTap = true, doubleTap = false;; 
    float stopX, stopY, startX, startY; 
    RectF area_rect; 
    TapCounter tapCounter = new TapCounter(TAP_MAX_DELAY, TAP_MAX_DELAY); 

    public TripleTapView(Context context) { 
     super(context); 
     this.context = context; 
     paint = new Paint(); 
     paint.setColor(Color.GREEN); 
     paint.setAntiAlias(true); 
     paint.setDither(true); 
     paint.setStyle(Paint.Style.FILL); 
     paint.setStrokeJoin(Paint.Join.ROUND); 
     paint.setStrokeCap(Paint.Cap.ROUND); 
     paint.setStrokeWidth(2); 
    } 

    @SuppressLint("DrawAllocation") 
    @Override 
    protected void onDraw(final Canvas canvas) { 
     super.onDraw(canvas); 
     for (CustomPoint point_temp : point) { 
      // For changing tap circle color based on tap count 
      switch (point_temp.count) { 
      case 1: 
       paint.setColor(Color.YELLOW); 
       break; 
      case 2: 
       paint.setColor(Color.GREEN); 
       break; 
      case 3: 
       paint.setColor(Color.RED); 
       break; 
      } 
      canvas.drawCircle(point_temp.point.x, point_temp.point.y, 10, paint); 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      stopX = event.getX(); 
      stopY = event.getY(); 
      if (firstTap) { 
       addFirstTap(); 
      } else if (doubleTap) { 
       prevTime = thisTime; 
       thisTime = new Date().getTime(); 
       if (thisTime > prevTime) { 
        if ((thisTime - prevTime) <= TAP_MAX_DELAY) { 
         if (area_rect.contains(stopX, stopY)) 
          doubleTap = false; 
         else { 
          addPoint(1); 
          addFirstTap(); 
         } 
        } else { 
         addPoint(1); 
         firstTap = true; 
        } 
       } else { 
        firstTap = true; 
       } 
      } else { 
       prevTime = thisTime; 
       thisTime = new Date().getTime(); 
       if (thisTime > prevTime) { 
        if ((thisTime - prevTime) <= TAP_MAX_DELAY) { 
         if (area_rect.contains(stopX, stopY)) { 
          addPoint(3); 
          firstTap = true; 
         } else { 
          addPoint(2); 
          addFirstTap(); 
         } 
        } else { 
         addPoint(2); 
         firstTap = true; 
        } 
       } else { 
        firstTap = true; 
       } 
      } 
     } 
     return true; 
    } 

    void addPoint(int tapCount) { 
     point.add(new CustomPoint(new PointF(startX, startY), tapCount)); 
     invalidate(); 
    } 

    void addFirstTap() { 
     thisTime = new Date().getTime(); 
     firstTap = false; 
     doubleTap = true; 
     startX = stopX; 
     startY = stopY; 
     area_rect = new RectF(stopX - RADIUS, stopY - RADIUS, stopX + RADIUS, 
       stopY + RADIUS); 
     tapCounter.resetCounter(); 
    } 

    class TapCounter extends CountDownTimer { 
     public TapCounter(long millisInFuture, long countDownInterval) { 
      super(millisInFuture, countDownInterval); 
     } 

     @Override 
     public void onFinish() { 
      if (doubleTap) { 
       prevTime = thisTime; 
       thisTime = new Date().getTime(); 
       if (thisTime > prevTime) { 
        if ((thisTime - prevTime) <= TAP_MAX_DELAY) { 
         doubleTap = false; 
        } else { 
         addPoint(1); 
         firstTap = true; 
        } 
       } else { 
        firstTap = true; 
       } 
      } else if (!firstTap && !doubleTap) { 
       prevTime = thisTime; 
       thisTime = new Date().getTime(); 
       if (thisTime > prevTime) { 
        if ((thisTime - prevTime) <= TAP_MAX_DELAY) { 
         addPoint(2); 
         firstTap = true; 
        } 
       } else { 
        firstTap = true; 
       } 
      } 
     } 

     @Override 
     public void onTick(long millisUntilFinished) { 
     } 

     public void resetCounter() { 
      start(); 
     } 
    } 
} 

請幫我解決這個問題。

回答

8

此代碼將執行您所需的操作。我簡化了你的課程。

import java.util.ArrayList; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PointF; 
import android.graphics.RectF; 
import android.os.CountDownTimer; 
import android.view.MotionEvent; 
import android.view.View; 

public class TripleTapView extends View { 

    // Set the tap delay in milliseconds 
    protected static final long TAP_MAX_DELAY = 500L; 
    // Radius to capture tap within bound 
    private final static int RADIUS = 30; 
    // Store all points with tap count 
    public ArrayList<CustomPoint> _points = new ArrayList<CustomPoint>(); 

    Context _context; 
    Paint _paint; 

    TapCounter _tapCounter = new TapCounter(TAP_MAX_DELAY, TAP_MAX_DELAY); 

    public TripleTapView(Context context) { 
     super(context); 
     _context = context; 

     _paint = new Paint(); 
     _paint.setAntiAlias(true); 
     _paint.setDither(true); 
     _paint.setStyle(Paint.Style.FILL); 
     _paint.setStrokeJoin(Paint.Join.ROUND); 
     _paint.setStrokeCap(Paint.Cap.ROUND); 
     _paint.setStrokeWidth(2); 
    } 

    @Override 
    protected void onDraw(final Canvas canvas) { 
     super.onDraw(canvas); 
     for (CustomPoint point_temp : _points) { 
      // For changing tap circle color based on tap count 
      switch (point_temp.count) { 
      case 1: 
       _paint.setColor(Color.YELLOW); 
       break; 
      case 2: 
       _paint.setColor(Color.GREEN); 
       break; 
      case 3: 
       _paint.setColor(Color.RED); 
       break; 
      } 
      canvas.drawCircle(point_temp.point.x, point_temp.point.y, 10, 
        _paint); 
     } 
    } 

    private RectF _lastTapArea; 
    private int _lastTapCount = 0; 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      _tapCounter.resetCounter(); 
      float x = event.getX(); 
      float y = event.getY(); 

      if (_lastTapArea != null) { 
       if (_lastTapArea.contains(x, y)) { 
        if (_lastTapCount < 3) { 
         _lastTapCount++; 
        } else { 
         addPoint(_lastTapArea.centerX(), 
           _lastTapArea.centerY(), _lastTapCount); 
         _lastTapCount = 1; 
        } 
       } else { 
        addPoint(_lastTapArea.centerX(), _lastTapArea.centerY(), 
          _lastTapCount); 
        _lastTapCount = 1; 
        _lastTapArea = new RectF(x - RADIUS, y - RADIUS, 
          x + RADIUS, y + RADIUS); 
       } 
      } else { 
       _lastTapCount = 1; 
       _lastTapArea = new RectF(x - RADIUS, y - RADIUS, x + RADIUS, y 
         + RADIUS); 
      } 

      return true; 
     } 

     return false; 
    } 

    void addPoint(float x, float y, int tapCount) { 
     _points.add(new CustomPoint(new PointF(x, y), tapCount)); 
     invalidate(); 
    } 

    class TapCounter extends CountDownTimer { 

     public TapCounter(long millisInFuture, long countDownInterval) { 
      super(millisInFuture, countDownInterval); 
     } 

     @Override 
     public void onFinish() { 
      if (_lastTapArea != null) { 
       if (_lastTapCount > 0) 
        addPoint(_lastTapArea.centerX(), _lastTapArea.centerY(), 
          _lastTapCount); 

       _lastTapCount = 0; 
       _lastTapArea = null; 
      } 
     } 

     @Override 
     public void onTick(long millisUntilFinished) { 
     } 

     public void resetCounter() { 
      start(); 
     } 
    } 
} 
相關問題