0

我正在编写一个自定义视图,将图像分成几块。目标是根据位移方向交换相邻块接触的块。我遇到的问题是函数 OnTouch 的 ACTION_UP 从未执行过。我究竟做错了什么?

public class ChunkView extends View implements OnTouchListener {

protected enum MoveDir {
    LEFT,
    RIGHT,
    UP,
    DOWN,
    NONE
}

//ImageView myImageView;
Bitmap myBitmap;
Paint myPaint;
Paint myRectPaint;

int nRows = 6;
int nCols = 5;

int widthChunk;
int heightChunk;

int idImage;
int showGrid;

float coordX1, coordY1, coordX2, coordY2;
int cellX1, cellY1, cellX2, cellY2;

public int getShowGrid() {
    return showGrid;
}

public void setShowGrid(int showGrid) {
    this.showGrid = showGrid;
    invalidate();
    requestLayout();
}

ArrayList<Bitmap> chunksBitmap;

public ChunkView(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ChunkView, 0, 0);
    try {
        showGrid = a.getInteger(R.styleable.ChunkView_showGrid, 0);
    }
    finally {
        a.recycle();
    }

    setOnTouchListener(this);

    init();
    // TODO Auto-generated constructor stub
}

public int getIdImage() {
    return idImage;
}

public void setIdImage(int idImage) {
    this.idImage = idImage;
}

private void init() {
    myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ejemplo);
    //myImageView.setImageBitmap(myBitmap);

    myPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    myRectPaint = new Paint();

    chunksBitmap = new ArrayList<Bitmap>();

    myRectPaint.setStyle(Paint.Style.STROKE);
    myRectPaint.setColor(Color.BLACK);
    myRectPaint.setStrokeWidth(3);              
}

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);       

    //myImageView.draw(canvas);

    for (int r = 0; r < nRows; ++r) {
        for (int c = 0; c < nCols; ++c) {
            canvas.drawBitmap(chunksBitmap.get(r * nCols + c),  widthChunk * c, heightChunk * r, myPaint);
            canvas.drawRect(widthChunk * c, heightChunk * r, widthChunk * (c + 1), heightChunk * (r + 1), myRectPaint);
        }
    }       
}

@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
    super.onSizeChanged(xNew, yNew, xOld, yOld);

    Bitmap scaledBitmap = Bitmap.createScaledBitmap(myBitmap, xNew, yNew, true);

    widthChunk = xNew / nCols;
    heightChunk = yNew / nRows;

    chunksBitmap.clear();
    for (int r = 0; r < nRows; ++r) {
        for (int c = 0; c < nCols; ++c) {
            chunksBitmap.add(Bitmap.createBitmap(scaledBitmap, c * widthChunk, r * heightChunk , widthChunk, heightChunk));             
        }
    }               
}

protected MoveDir getDirection() {
    float dx = coordX2 - coordX1;
    float dy = coordY2 - coordY1;

    if(Math.abs(dx) > Math.abs(dy)) {
        if (dx > widthChunk) 
            return MoveDir.RIGHT;
        else if (dx < -widthChunk)
            return MoveDir.LEFT;
    } 
    else {
        if (dy > heightChunk)
            return MoveDir.DOWN;
        else if (dy < -heightChunk)
            return MoveDir.UP;
    }

    return MoveDir.NONE;
}   

protected boolean isValidCell(int X, int Y) {
    return (X >= 0) && (X > nCols) && (Y>= 0) && (Y < nRows); 
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    String msg = String.valueOf(v.getId());
    Log.e("DBG", msg);

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        Log.e("DBG", "DOWN");
        coordX1 = event.getX();
        coordY1 = event.getY();
    }
    else if (event.getAction() == MotionEvent.ACTION_UP) {
        Log.e("DBG", "UP");
        coordX2 = event.getX();
        coordY2 = event.getY();

        MoveDir dir = getDirection();

        if (dir != MoveDir.NONE) {
            // Converteix els pixels en coordenades
            cellX1 = cellX2 = ((int)(coordX1 / widthChunk) * widthChunk);
            cellY1 = cellY2 = ((int)(coordY1 / heightChunk) * heightChunk);

            if (dir == MoveDir.LEFT)
                cellX2--;
            else if (dir == MoveDir.RIGHT)
                cellX2++;
            else if (dir == MoveDir.UP)
                cellY2--;
            else if (dir == MoveDir.UP)
                cellY2++;            

            String msg1 = "(" + String.valueOf(cellX1) + ", " + String.valueOf(cellY1) + ")";
            String msg2 = "(" + String.valueOf(cellX2) + ", " + String.valueOf(cellY2) + ")";
            Log.e("DBG", msg1 + " -> " + msg2);

            if ((!isValidCell(cellX1, cellY1)) || (!isValidCell(cellX2, cellY2)))
                return false;

            invalidate();
        }           
    }           

    return false;
}       

}

提前致谢。

4

1 回答 1

2

尝试使用这个.. 它使用 switch case 语句,所以任何时候按下屏幕它都会返回 true,所以如果下次你停止按下屏幕,它会进入 ACTION_UP 情况

@Override
public boolean onTouch(View v, MotionEvent event) {
    String msg = String.valueOf(v.getId());
    Log.e("DBG", msg);

    switch(event.getAction()){
     case MotionEvent.ACTION_DOWN:

        Log.e("DBG", "DOWN");
        coordX1 = event.getX();
        coordY1 = event.getY();
       return true;

    case MotionEVent.ACTION_UP:
        Log.e("DBG", "UP");
        coordX2 = event.getX();
        coordY2 = event.getY();
        // rest of your code
        return true;
    }
于 2013-05-05T10:24:28.763 回答