0

我正在尝试更熟悉 AndroidSurfaceView类,并在此过程中尝试创建一个简单的应用程序,允许用户Bitmap在屏幕上移动 a。这个实现的麻烦部分是我还包括用户可以在放置图像后再次拖动图像的功能。为了做到这一点,我将位图映射到一组简单的坐标,这些坐标定义了Bitmap的当前位置。但是,我将图像映射到的区域与图像不匹配。

问题

SurfaceViewusing上canvas.drawBitmap()放置图像并记录放置图像的坐标后,我设置的映射系统Bitmap以某种方式误解了 的坐标并且无法正确显示。正如你在这张图片中看到的那样,我只是简单地用canvas.drawLine()线条来表示我的触摸区域的空间,并且图像总是在右边:

.png 和纹理区域始终处于关闭状态!

编码

在这里,我将提供相关的代码摘录来帮助回答我的问题。

CustomSurface.java

此方法将对象的绘制封装到画布上。评论阐明了每个要素:

public void onDraw(Canvas c){

    //Simple black paint
    Paint paint = new Paint();

    //Draw a white background
    c.drawColor(Color.WHITE);

    //Draw the bitmap at the coordinates
    c.drawBitmap(g.getResource(), g.getCenterX(), g.getCenterY(), null);

    //Draws the actual surface that is receiving touch input
    c.drawLine(g.left, g.top, g.right, g.top, paint);
    c.drawLine(g.right, g.top, g.right, g.bottom, paint);
    c.drawLine(g.right, g.bottom, g.left, g.bottom, paint);
    c.drawLine(g.left, g.bottom, g.left, g.top, paint);
}

此方法封装了我如何捕获触摸事件:

public boolean onTouchEvent(MotionEvent e){

    switch(e.getAction()){

        case MotionEvent.ACTION_DOWN:{

            if(g.contains((int) e.getX(), (int) e.getY()))
                item_selected = true;
            break;
        }
        case MotionEvent.ACTION_MOVE:{

            if(item_selected)      
                g.move((int) e.getX(), (int) e.getY());

            break;
        }
        case MotionEvent.ACTION_UP:{

            item_selected = false;
            break;
        }
        default:{

            //Do nothing
            break;
        }
    }

    return true;
}

图形.java

此方法用于构造图形:

//Initializes the graphic assuming the coordinate is in the upper left corner
public Graphic(Bitmap image, int start_x, int start_y){

    resource = image;
    left = start_x;
    top = start_y;
    right = start_x + image.getWidth();
    bottom = start_y + image.getHeight();
}

此方法检测用户是否在图像内部单击:

public boolean contains(int x, int y){

    if(x >= left && x <= right){

        if(y >= top && y <= bottom){

            return true;
        }
    }

    return false;
}

此方法用于移动图形:

public void move(int x, int y){

    left = x;
    top = y;
    right = x + resource.getWidth();
    bottom = y + resource.getHeight();
}

我还有两种方法可以确定区域的中心(用于重绘):

public int getCenterX(){

    return (right - left) / 2 + left;
}

public int getCenterY(){

    return (bottom - top) / 2 + top;
}

任何帮助将不胜感激,我觉得许多其他 StackOverflow 用户真的可以从这个问题的解决方案中受益。

4

2 回答 2

1

在 Android 开发者博客上有一个关于触摸/多点触控/手势的非常好的和彻底的解释,其中包括google code 上的免费和开源代码示例

请看一下。如果您不需要手势 - 只需跳过该部分,仅阅读有关触摸事件的内容。

于 2012-11-14T01:50:09.113 回答
0

这个问题最终比我想象的要简单得多,经过一些调整后,我意识到这是一个图像宽度补偿的问题。

上面代码中的这一行是错误的来源:

c.drawBitmap(g.getResource(), g.getCenterX(), g.getCenterY(), null);

正如你所知道的,我在Graphic类中操纵坐标来生成位图的中心,然后调用canvas.drawBitmap()它,假设它将从中心向外绘制。

显然,这是行不通的,因为画布总是从图像的左上角向下和向右下降,所以解决方案很简单。

解决方案

根据触摸位置创建触摸区域,但绘制它的距离等于从 x 和 y 方向的中心位置减去图像宽度的距离。我基本上更改了Graphic类的体系结构以实现一个getDrawX()andgetDrawY()方法,该方法将返回修改后的x坐标y和应该绘制的位置,以便使center_xandcenter_y值(在构造函数中确定)实际上看起来位于区域的中心。

这一切都归结为这样一个事实,即为了弥补画布绘制位图的方式,我不幸加入了一些不良行为,最终不得不以完全不同的方式处理偏移量。

于 2012-11-14T03:15:20.583 回答