Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 识别自定义视图上的三次点击_Android_Canvas_Android Widget_Touch Event - Fatal编程技术网

Android 识别自定义视图上的三次点击

Android 识别自定义视图上的三次点击,android,canvas,android-widget,touch-event,Android,Canvas,Android Widget,Touch Event,我想画一个圆圈,每当用户点击自定义视图时,根据点击次数,圆圈的颜色会发生变化 Single Tap : YELLOW CIRCLE Double Tap : GREEN CIRCLE Triple Tap : RED COLOR 问题是,我创建了一个自定义视图,它将根据时间统计点击事件,但有时它会错过第一次点击。这导致了问题的出现 下面的代码显示了我为创建上述自定义视图所做的所有努力 TripleTapView package com.slk.car_rating_app; import j

我想画一个圆圈,每当用户点击自定义视图时,根据点击次数,圆圈的颜色会发生变化

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();
        }
    }
}
package com.slk.car\u rating\u应用程序;
导入java.util.ArrayList;
导入java.util.Date;
导入android.annotation.SuppressLint;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.PointF;
导入android.graphics.RectF;
导入android.os.CountDownTimer;
导入android.view.MotionEvent;
导入android.view.view;
公共类TripleTapView扩展了视图{
//以毫秒为单位设置点击延迟
受保护的静态最终长抽头最大延迟=500L;
//在边界内捕获攻丝的半径
最终静态整数半径=30;
//使用抽头计数存储所有点
public ArrayList point=new ArrayList();
//访问视图的上下文
语境;
油漆;
private long ThistTime=0,prevTime=0;
私有布尔值firstTap=true,doubleTap=false;;
浮动stopX、stopY、startX、startY;
RectF区域;
TapCounter TapCounter=新的TapCounter(TAP_MAX_DELAY,TAP_MAX_DELAY);
公共TripleTapView(上下文){
超级(上下文);
this.context=上下文;
油漆=新油漆();
油漆。设置颜色(颜色。绿色);
paint.setAntiAlias(真);
绘制。设置抖动(真);
绘制.设置样式(绘制.样式.填充);
绘制.设置行程连接(绘制.连接.圆形);
油漆固定行程盖(油漆固定行程盖圆形);
油漆。设置行程宽度(2);
}
@SuppressLint(“DrawAllocation”)
@凌驾
受保护的void onDraw(最终画布){
super.onDraw(帆布);
用于(自定义点温度:点){
//用于根据点击次数更改点击圆颜色
开关(点温度计数){
案例1:
油漆。设置颜色(颜色。黄色);
打破
案例2:
油漆。设置颜色(颜色。绿色);
打破
案例3:
油漆。设置颜色(颜色。红色);
打破
}
画布画圈(点x、点y、点10、油漆);
}
}
@凌驾
公共布尔onTouchEvent(运动事件){
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
stopX=event.getX();
stopY=event.getY();
如果(第一次点击){
addFirstTap();
}else if(双击){
prevTime=这次;
ThistTime=新日期().getTime();
如果(这次>上次){
如果((ThistTime-prevTime)prevTime){
如果((ThistTime-prevTime)prevTime){
如果((ThistTime-prevTime)prevTime){

如果((thisTime-prevTime)这段代码可以满足您的需要。我简化了您的类

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();
        }
    }
}
import java.util.ArrayList;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.PointF;
导入android.graphics.RectF;
导入android.os.CountDownTimer;
导入android.view.MotionEvent;
导入android.view.view;
公共类TripleTapView扩展了视图{
//以毫秒为单位设置点击延迟
受保护的静态最终长抽头最大延迟=500L;
//在边界内捕获攻丝的半径
专用最终静态整数半径=30;
//使用抽头计数存储所有点
public ArrayList_points=new ArrayList();
语境(Context)语境;;
油漆;
TapCounter\u TapCounter=新的TapCounter(TAP\u MAX\u DELAY,TAP\u MAX\u DELAY);
公共TripleTapView(上下文){
超级(上下文);
_上下文=上下文;
_油漆=新油漆();
_paint.setAntiAlias(真);
_绘制。设置抖动(真);
_绘制.设置样式(绘制.样式.填充);
_绘制.设置行程连接(绘制.连接.圆形);
_油漆固定行程盖(油漆固定行程盖圆形);
_油漆。设置行程宽度(2);
}
@凌驾
受保护的void onDraw(最终画布){
super.onDraw(帆布);
用于(自定义点温度:_点){
//用于根据点击次数更改点击圆颜色
开关(点温度计数){
案例1:
_油漆。设置颜色(颜色。黄色);
打破
案例2:
_油漆。设置颜色(颜色。绿色);
打破
案例3:
_油漆。设置颜色(颜色。红色);
打破
}
画布绘制圆(点x、点y、点10、,
_油漆);
}
}
私人住宅区;
私有整数_lastTapCount=0;
@凌驾
公共布尔onTouchEvent(运动事件){
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
_tapCounter.resetCounter();
float x=event.getX();
float y=event.getY();
如果(_lastTapArea!=null){
if(_lastTapArea.contains(x,y)){
如果(_lastTapCount<3){
_lastTapCount++;
}否则{
addPoint(_lastTapArea.centerX(),
_lastTapArea.centerY(),_lastTapCount);
_lastTapCount=1;
}
}否则{
添加点(_lastTapArea.centerX(),_lastTapArea.centerY(),
_最后计数);
_lastTapCount=1;
_lastTapArea=新的矩形(x-半径,y-半径,
x+半径,y+半径);