Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.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:使用onDraw和onTouchEvent绘制线条渲染速度慢_Android_Android Custom View_Touch Event_Ondraw_Custom View - Fatal编程技术网

Android:使用onDraw和onTouchEvent绘制线条渲染速度慢

Android:使用onDraw和onTouchEvent绘制线条渲染速度慢,android,android-custom-view,touch-event,ondraw,custom-view,Android,Android Custom View,Touch Event,Ondraw,Custom View,我尝试使用ontouch方法和onDraw方法绘制四条线,如下所示: @Override protected void onDraw(Canvas canvas) { initPoints(); path.reset(); path.addCircle(topLeftPoint.x,topLeftPoint.y, 16f, Path.Direction.CW); canvas.drawLi

我尝试使用ontouch方法和onDraw方法绘制四条线,如下所示:

 @Override
       protected void onDraw(Canvas canvas) {
        initPoints();
        path.reset();
        path.addCircle(topLeftPoint.x,topLeftPoint.y, 16f,       
       Path.Direction.CW);
        canvas.drawLines(points, paint);

        path.addCircle(middleTopPoint.x, middleTopPoint.y, 16f, Path.Direction.CW);
        path.addCircle(topRightPoint.x, topRightPoint.y, 16f, Path.Direction.CW);

//      canvas.drawLine(topRightPoint.x, topRightPoint.y, bottomRightPoint.x, bottomRightPoint.y, paint);
        path.addCircle(bottomRightPoint.x, bottomRightPoint.y, 16f, Path.Direction.CW);

        path.addCircle(middleRightPoint.x, middleRightPoint.y, 16f, Path.Direction.CW);
//      canvas.drawLine(bottomRightPoint.x, bottomRightPoint.y, bottomLeftPoint.x, bottomLeftPoint.y, paint);
        path.addCircle(bottomLeftPoint.x, bottomLeftPoint.y, 16f, Path.Direction.CW);
        path.addCircle(middleBottomPoint.x, middleBottomPoint.y, 16f, Path.Direction.CW);

//      canvas.drawLine(bottomLeftPoint.x, bottomLeftPoint.y, topLeftPoint.x, topLeftPoint.y, paint);
        path.addCircle(topRightPoint.x, topRightPoint.y, 16f, Path.Direction.CW);
        path.addCircle(middleLeftPoint.x, middleLeftPoint.y, 16f, Path.Direction.CW);
        path.close();
        canvas.drawPath(path, paint);
            }

    @Override
    public boolean onTouchEvent(final MotionEvent event) {

        int action = event.getActionMasked();

        if (event.getAction() == MotionEvent.ACTION_DOWN ||
                event.getAction() == MotionEvent.ACTION_MOVE
                || event.getAction() == MotionEvent.ACTION_UP) {

            float xCoordinate = 16;
            float yCoordinate = 16;

            if (event.getX() < 16) {
                xCoordinate = 16;
            } else if (event.getX() > getWidth() - 16) {
                xCoordinate = getWidth() - 16;
            } else {
                xCoordinate = event.getX();
            }

            if (event.getY() < 16) {
                yCoordinate = 16;
            } else if (event.getY() > getHeight() - 16) {
                yCoordinate = getHeight() - 16;
            } else {
                yCoordinate = event.getY();
            }
            if (isInsideTopLeft(event.getX(), event.getY())) {
                topLeftPoint.set(xCoordinate, yCoordinate);

                middleTopPoint.set((topRightPoint.x + topLeftPoint.x) / 2,
                        (topRightPoint.y + topLeftPoint.y) / 2);
                middleLeftPoint.set((bottomLeftPoint.x + topLeftPoint.x) / 2,
                        (bottomLeftPoint.y + topLeftPoint.y) / 2);
                invalidate();
                return true;
            } else if (isInsideTopRight(event.getX(), event.getY())) {
                topRightPoint.set(xCoordinate, yCoordinate);

                middleTopPoint.set((topRightPoint.x + topLeftPoint.x) / 2,
                        (topRightPoint.y + topLeftPoint.y) / 2);
                middleRightPoint.set((bottomRightPoint.x + topRightPoint.x) / 2,
                        (bottomRightPoint.y + topRightPoint.y) / 2);
                invalidate();
                return true;
            } else if (isInsideBottomRight(event.getX(), event.getY())) {
                bottomRightPoint.set(xCoordinate, yCoordinate);

                middleBottomPoint.set((bottomLeftPoint.x + bottomRightPoint.x) / 2,
                        (bottomLeftPoint.y + bottomRightPoint.y) / 2);
                middleRightPoint.set((bottomRightPoint.x + topRightPoint.x) / 2,
                        (bottomRightPoint.y + topRightPoint.y) / 2);
                invalidate();
                return true;
            } else if (isInsideBottomLeft(event.getX(), event.getY())) {
                bottomLeftPoint.set(xCoordinate, yCoordinate);

                middleBottomPoint.set((bottomLeftPoint.x + bottomRightPoint.x) / 2,
                        (bottomLeftPoint.y + bottomRightPoint.y) / 2);
                middleLeftPoint.set((bottomLeftPoint.x + topLeftPoint.x) / 2,
                        (bottomLeftPoint.y + topLeftPoint.y) / 2);
                invalidate();
                return true;
            } 
        }

        return super.onTouchEvent(event);
    }   
@覆盖
受保护的void onDraw(画布){
initPoints();
path.reset();
path.addCircle(topLeftPoint.x,topLeftPoint.y,16f,
路径。方向。CW);
帆布。抽绳(点、油漆);
添加圆(middletopoint.x,middletopoint.y,16f,path.Direction.CW);
添加圆(topRightPoint.x,topRightPoint.y,16f,path.Direction.CW);
//画布.抽绳(topRightPoint.x,topRightPoint.y,bottomRightPoint.x,bottomRightPoint.y,绘制);
添加圆(bottomRightPoint.x,bottomRightPoint.y,16f,path.Direction.CW);
添加圆(middleRightPoint.x,middleRightPoint.y,16f,path.Direction.CW);
//画布.抽绳(bottomRightPoint.x,bottomRightPoint.y,bottomLeftPoint.x,bottomLeftPoint.y,绘制);
addCircle(bottomLeftPoint.x,bottomLeftPoint.y,16f,path.Direction.CW);
添加圆(中间点x,中间点y,16f,路径方向CW);
//画布绘制线(bottomLeftPoint.x,bottomLeftPoint.y,topLeftPoint.x,topLeftPoint.y,绘制);
添加圆(topRightPoint.x,topRightPoint.y,16f,path.Direction.CW);
添加圆(middleftpoint.x,middleftpoint.y,16f,path.Direction.CW);
path.close();
画布.绘制路径(路径,绘制);
}
@凌驾
公共布尔onTouchEvent(最终运动事件){
int action=event.getActionMasked();
如果(event.getAction()==MotionEvent.ACTION\u向下||
event.getAction()==MotionEvent.ACTION\u MOVE
||event.getAction()==MotionEvent.ACTION\u UP){
浮点数xCoordinate=16;
浮动yCoordinate=16;
if(event.getX()<16){
xCoordinate=16;
}else if(event.getX()>getWidth()-16){
xCoordinate=getWidth()-16;
}否则{
xCoordinate=event.getX();
}
if(event.getY()<16){
yCoordinate=16;
}else if(event.getY()>getHeight()-16){
yCoordinate=getHeight()-16;
}否则{
yCoordinate=event.getY();
}
if(isInsideTopLeft(event.getX(),event.getY()){
topLeftPoint.set(xCoordinate,yCoordinate);
middleTopPoint.set((topRightPoint.x+topLeftPoint.x)/2,
(右上角点y+左上角点y)/2);
middleftpoint.set((bottomLeftPoint.x+topLeftPoint.x)/2,
(底部leftpoint.y+顶部leftpoint.y)/2);
使无效();
返回true;
}else if(isInsideTopRight(event.getX(),event.getY()){
topRightPoint.set(xCoordinate,yCoordinate);
middleTopPoint.set((topRightPoint.x+topLeftPoint.x)/2,
(右上角点y+左上角点y)/2);
middleRightPoint.set((bottomRightPoint.x+topRightPoint.x)/2,
(右下角点y+右上角点y)/2);
使无效();
返回true;
}else if(isInsideBottomRight(event.getX(),event.getY()){
右下角点集(xCoordinate,yccoordinate);
中间底部点.set((bottomLeftPoint.x+bottomRightPoint.x)/2,
(bottomLeftPoint.y+bottomRightPoint.y)/2);
middleRightPoint.set((bottomRightPoint.x+topRightPoint.x)/2,
(右下角点y+右上角点y)/2);
使无效();
返回true;
}else if(isInsideBottomLeft(event.getX(),event.getY()){
底部左端点集(xCoordinate,yccoordinate);
中间底部点.set((bottomLeftPoint.x+bottomRightPoint.x)/2,
(bottomLeftPoint.y+bottomRightPoint.y)/2);
middleftpoint.set((bottomLeftPoint.x+topLeftPoint.x)/2,
(底部leftpoint.y+顶部leftpoint.y)/2);
使无效();
返回true;
} 
}
返回super.onTouchEvent(事件);
}   
但是当我增加触摸速度时,渲染速度变慢了。 我已经使用了路径和线,但性能的提高仍然很小

我从代码中删除的其他方法,如声明PointF对象和使用默认值启动这些对象

如果有人有任何想法,我将不胜感激

致以最良好的祝愿,
AurelianR

如果没有完整的代码,很难检查可能需要改进的地方。 您正在调用initPoints()并在每次绘制调用时重置路径

如果在触摸事件中考虑以下情况:

if (isInsideTopLeft(event.getX(), event.getY())) {
      // update topLeftPoint, middleTopPoint and middleLeftPoint.
        invalidate();
        return true;
    }
然后在onDraw()中

只有三个调用更新了rest 6路径更新,可以避免。可以使用postInvalidate(dirtyRect)。
如果您添加了完整的代码(以及基本注释),那么我可以通过运行它进行检查。

您的问题与性能无关,而是触摸处理的错误执行。触摸处理概念简介:您的视图获得以下触摸事件的

操作:用户将手指放在视图上时接收(一次性)。总是生成

动作\移动:当用户移动手指时接收(多次)。如果用户不移动手指,则不会生成此事件

动作提示:当用户将手指从您的视线中抬起时收到(一次)。总是生成

向下直到向上完成一个周期的触摸事件,用户可以多次触摸您的视图

您的代码:

if (event.getAction() == MotionEvent.ACTION_DOWN ||
            event.getAction() == MotionEvent.ACTION_MOVE
            || event.getAction() == MotionEvent.ACTION_UP){

    if(isInsideTopLeft()){
    // do something
    // return
    } 
    // do same for other cases also.
}
这样,您每次都在计算案例(isInsideTopLeft()等),这会导致删除触摸事件(任何案例都不包括该事件)。你呢
if (event.getAction() == MotionEvent.ACTION_DOWN ||
            event.getAction() == MotionEvent.ACTION_MOVE
            || event.getAction() == MotionEvent.ACTION_UP){

    if(isInsideTopLeft()){
    // do something
    // return
    } 
    // do same for other cases also.
}
//create touch lock cases 
private final int TOUCH_STATE_UNLOCKED = 0;
private final int TOUCH_STATE_LOCKED_TOP_LEFT = 1;
private final int TOUCH_STATE_LOCKED_TOP_RIGHT = 2;
private final int TOUCH_STATE_LOCKED_BOTTOM_LEFT = 3;
private final int TOUCH_STATE_LOCKED_BOTTOM_RIGHT = 4;
private final int TOUCH_STATE_LOCKED_MIDDLE_LEFT = 5;
private final int TOUCH_STATE_LOCKED_MIDDLE_BOTTOM = 6;

private int TOUCH_STATE = TOUCH_STATE_UNLOCKED;

 @Override
public boolean onTouchEvent(final MotionEvent event) {

    int action = event.getActionMasked();
    float xCoordinate = 16;
    float yCoordinate = 16;
    int eventX = (int) event.getX();
    int eventY = (int) event.getY();

    if (eventX < 16) {
        xCoordinate = 16;
    } else if (eventX > getWidth() - 16) {
        xCoordinate = getWidth() - 16;
    } else {
        xCoordinate = eventX;
    }

    if (eventY < 16) {
        yCoordinate = 16;
    } else if (eventY > getHeight() - 16) {
        yCoordinate = getHeight() - 16;
    } else {
        yCoordinate = eventY;
    }

    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        /* Touch event handling in brief,  read about touch event handling,

        in ACTION_DOWN lock touch event for a particular point.


         */
        case MotionEvent.ACTION_DOWN:

            // lock touch event for a point . subsequent touch events
            if (isInsideTopLeft(event.getX(), event.getY())) {
                TOUCH_STATE = TOUCH_STATE_LOCKED_TOP_LEFT;
            } else if (isInsideTopRight(event.getX(), event.getY())) {
                TOUCH_STATE = TOUCH_STATE_LOCKED_TOP_RIGHT;
            } else if (isInsideBottomLeft(event.getX(), event.getY())) {
                TOUCH_STATE = TOUCH_STATE_LOCKED_BOTTOM_LEFT;
            } else if (isInsideBottomRight(event.getX(), event.getY())) {
                TOUCH_STATE = TOUCH_STATE_LOCKED_BOTTOM_RIGHT;
            } else if (isInsideMiddleLeft(event.getX(), event.getY())) {
                TOUCH_STATE = TOUCH_STATE_LOCKED_MIDDLE_LEFT;
            } else if (isInsideMiddleBottom(event.getX(), event.getY())) {
                TOUCH_STATE = TOUCH_STATE_LOCKED_MIDDLE_BOTTOM;
            }
            Log.e(TAG, "onTouchEvent: TOUCH_STATE = " + TOUCH_STATE);
            break;

        case MotionEvent.ACTION_MOVE:
// simply check for locked case
            if (TOUCH_STATE == TOUCH_STATE_LOCKED_TOP_LEFT) {
                Log.e(TAG, "onTouchEvent: top left locked");
                topLeftPoint.set(xCoordinate, yCoordinate);

                middleTopPoint.set((topRightPoint.x + topLeftPoint.x) / 2,
                        (topRightPoint.y + topLeftPoint.y) / 2);
                middleLeftPoint.set((bottomLeftPoint.x + topLeftPoint.x) / 2,
                        (bottomLeftPoint.y + topLeftPoint.y) / 2);
                // working fine with full invalidate also.
                invalidate();
            }
            // handle other cases also
            break;

        case MotionEvent.ACTION_UP:
            TOUCH_STATE = TOUCH_STATE_UNLOCKED;  // unlock

    }
    return true;
}