Daniel
Daniel

Reputation: 1317

Adding View to RelativeLayout not respecting initial layout

I'm creating a word game, a bunch of square tiles on a board. I'm starting to implement the motion events of touching and moving tiles and having an issue. When I touch a tile (ACTION_DOWN) I remove it from it's current view and move it to another parent view.. I set it's new layout but that layout isn't respected, the tile moves to 0,0 in the new view. I have the same code for defining the tile position in the ACTION_MOVE event, and there it acts as expected. So what i see is I touch a tile, it pops to 0,0 in the new view, then as I move my finger it pops back under my finger and moves as I would expect. Here's the code:

My Tile class extends View and my board class TileViewContainer extends RelativeLayout.

When I create a tile I register it for touch events like so:

TileViewContainer gameBoard = (TileViewContainer) findViewById(R.id.gameBoard);
tile.setOnTouchListener(gameBoard);

Here's my OnTouchListener:

    @Override
public boolean onTouch(View v, MotionEvent event) {

    final int X = (int) event.getRawX();
    final int Y = (int) event.getRawY();

    if(tileBoard == null)
        tileBoard = (TileBoard) findViewById(R.id.tileBoard);
    if(tileTray == null)
        tileTray = (TileTray) findViewById(R.id.tileTray);

    Tile tile = (Tile) v;
    TileView parent = tile.lastParent;
    Rect rect = null;
    int size = tileBoard.mTileSize;

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

            //Add tile to container
            tile.removeParent();
            this.addView(tile);
            rect = new Rect(X-(size/2), Y-(size), X-(size/2)+size, Y-(size)+size);
            tile.layout(rect.left, rect.top, rect.right, rect.bottom);  
            break;

        case MotionEvent.ACTION_UP:
            print("action up");
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            print("pointer down");
            break;
        case MotionEvent.ACTION_POINTER_UP:
            print("pointer up");
            break;
        case MotionEvent.ACTION_MOVE:

            //Move tile
            rect = new Rect(X-(size/2) , Y-(size)  , X-(size/2)+size, Y-(size)+size);
            tile.layout(rect.left, rect.top, rect.right, rect.bottom);
            break;
    }

    this.invalidate();
    return true;   

}

Upvotes: 1

Views: 65

Answers (1)

Daniel
Daniel

Reputation: 1317

I found a solution for anyone else running into this. I changed the ACTION_DOWN case from:

//Add tile to container
tile.removeParent();
this.addView(tile);
rect = new Rect(X-(size/2), Y-(size), X-(size/2)+size, Y-(size)+size);   
tile.layout(rect.left, rect.top, rect.right, rect.bottom); 
break;

To this:

//Add tile to container
tile.removeParent();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(sizeScaled, sizeScaled);
params.leftMargin = X-sizeScaled/2;
params.topMargin = Y-sizeScaled;
addView(tile, params);
break;

Seems I needed to create a new LayoutParams for the initial placement. Setting tile.layout in the move section still works fine.

Upvotes: 1

Related Questions