0

我坚持在 android 的表面中添加放大和缩小功能,我的代码如下。我已经实现了 SurfaceView 和 SurfaceHoder.CallBack。我在 Xml 文件中使用这个自定义视图。并显示一个拼字游戏板,但我无法在游戏板中添加放大和缩小功能。

package com.scrabble.game.client.ui; 

public class BoardView extends SurfaceView implements SurfaceHolder.Callback,
        OnTouchListener {

    private static int BOARD_SIZE = 15;
    private static final float MIN_FONT_DIPS = 10.0f;

    private static final int[] STACK_COLOR = { 0xFFFFFFFF, 0xFF2BC2AE,
            0xFF2BC241, 0xFF9FA617, 0xFFC76B50 };

    private Dimensions dimensions;    
    private DrawingThread thread;

    class DrawingThread extends Thread implements OnTouchListener {
        private static final int TRAY_AREA = 1;
        private static final int BOARD_AREA = 2;
        private static final int SCORE_AREA = 3;
        // private static final String STACK_MESSAGE = "Tile Stack";

        private boolean mRun;
        private SurfaceHolder mSurfaceHolder;

        private Dimensions dims;
        private GameEngine ge;
        private int defaultFontS;
        private PopupWindow pw;

        private int event;
        private int eventX, eventY;
        private int prevEventX, prevEventY;

        private Handler mHandler;  


        private int selectedTileNum;
        private int selectedBoardTileX, selectedBoardTileY;
        private int movingTileX, movingTileY;

        // private int topLeftX, topLeftY;

        public DrawingThread(SurfaceHolder holder, Handler handler) {
            mSurfaceHolder = holder;
            mRun = false;
            switchMode = false;
            tileIsMoved = false;
            boardTileIsMoved = false;
            // stackOpen = false;
            // openStack = new TileStack();
            event = eventX = eventY = -1;
            prevEventX = prevEventY = -1;
            selectedTileNum = -1;
            selectedBoardTileX = -1;
            selectedBoardTileY = -1;
            movingTileX = -1;
            movingTileY = -1;
            // topLeftX = -1;
            // topLeftY = -1;
            mHandler = handler;
            dims = new Dimensions();
            movingTile = new Tile();
            defaultFontS = (int) BoardView.MIN_FONT_DIPS;
            ge = null;
            tilesTray = new Rect[1];
            paintInitialisation();
            setFocusable(true);
        }
        public void setRunning(boolean b) {
            mRun = b;
        }
        @Override
        public void run() {
            while (mRun) {
                Canvas c = null;
                try {
                    c = mSurfaceHolder.lockCanvas(null);
                    Rect bRect = new Rect(0, 0, dims.getTotalWidth(),
                            dims.getScoreHeight() + dims.getBoardheight());
                    // canvas.drawRect(bRect, fillBoardPaint);
                    Drawable drawableMain = getResources().getDrawable(
                            R.drawable.mainbg);
                    drawableMain.setBounds(bRect);
                    drawableMain.draw(c);
                    synchronized (mSurfaceHolder) {
                        updateGame();
                        doDraw(c);
                    }
                } finally {
                    if (c != null) {
                        mSurfaceHolder.unlockCanvasAndPost(c);
                    }
                }
            }
        }

        public void setSwitchMode(boolean b) {
            synchronized (mSurfaceHolder) {
                switchMode = b;
            }
        }

        public void setGameEngine(GameEngine ge) {
            synchronized (mSurfaceHolder) {
                this.ge = ge;
            }
        }

        public void setDimensions(Dimensions dimensions) {
            synchronized (mSurfaceHolder) {
                dims = dimensions;
            }
        }

        public void setEventInfo(int evt, int x, int y) {
            synchronized (mSurfaceHolder) {
                event = evt;
                eventX = x;
                eventY = y;
            }
        }

        public void setDefaultFontSize(int dfs) {
            synchronized (mSurfaceHolder) {
                defaultFontS = dfs;
            }
        }

        public void setPopupWindow(PopupWindow popUp) {
            synchronized (mSurfaceHolder) {
                this.pw = popUp;
            }
        }

        private void updateGame() {
            if (ge == null)
                return;

            switch (event) {
            case MotionEvent.ACTION_DOWN:
                int area = getArea(eventX, eventY);
                switch (area) {
                case TRAY_AREA:
                    handleTrayClick(eventX, eventY);
                    if (switchMode && selectedTileNum != -1) {
                        switchMode = false;
                        pw.dismiss();
                        ge.makeSwitch(selectedTileNum);
                        selectedTileNum = -1;
                    }
                    break;
                case BOARD_AREA:
                    handleBoardClick(eventX, eventY);
                    break;
                case SCORE_AREA:
                default:
                    break;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (Math.abs(prevEventX - eventX) < dims.getCellSize() / 20)
                    return;
                if (Math.abs(prevEventY - eventY) < dims.getCellSize() / 20)
                    return;
                // stackOpen = false;
                // openStack = null;
                if (selectedTileNum != -1) {
                    int turn = ge.getPlayerTurn();
                    Tray t = ge.getPlayer(turn).getTray();
                    if (!tileIsMoved)
                        movingTile = t.temporaryRemoveTile(selectedTileNum);
                    tileIsMoved = true;
                    movingTileX = getMovingTileXPos(eventX);
                    movingTileY = getMovingTileYPos(eventY);
                } else if (selectedBoardTileX != -1 && selectedBoardTileY != -1) {
                    Board b = ge.getBoard();
                    if (!tileIsMoved)
                        movingTile = b.removeTile(selectedBoardTileX,
                                selectedBoardTileY);
                    tileIsMoved = true;
                    boardTileIsMoved = true;
                    movingTileX = getMovingTileXPos(eventX);
                    movingTileY = getMovingTileYPos(eventY);
                }

                break;
            case MotionEvent.ACTION_UP:
                // stackOpen = false;
                // openStack = null;
                if (tileIsMoved) {
                    Board b = ge.getBoard();
                    int turn = ge.getPlayerTurn();
                    Tray t = ge.getPlayer(turn).getTray();
                    if (getArea(eventX, eventY) == BOARD_AREA) {
                        int i = findCellRow(eventY);
                        int j = findCellCol(eventX);
                        if (b.canAddTile(i, j, movingTile)) {
                            b.addTile(movingTile, i, j);
                            if (!boardTileIsMoved) {
                                t.addTempRemovedTile(movingTile,
                                        selectedTileNum);
                                t.useTile(selectedTileNum);
                            }
                            SoundManager.playSound(2, 1, 0);
                        } else {
                            if (boardTileIsMoved) {
                                b.addTile(movingTile, selectedBoardTileX,
                                        selectedBoardTileY);
                            } else {
                                t.addTempRemovedTile(movingTile,
                                        selectedTileNum);
                            }
                            SoundManager.playSound(3, 1, 0);
                        }
                    } else if (getArea(eventX, eventY) == TRAY_AREA) {
                        if (boardTileIsMoved) {
                            t.addTile(movingTile);
                            SoundManager.playSound(3, 1, 0);
                        } else if (selectedTileNum != -1) {
                            t.addTempRemovedTile(movingTile, selectedTileNum);
                            SoundManager.playSound(3, 1, 0);
                        }
                    } else {
                        if (selectedTileNum != -1) {
                            t.addTempRemovedTile(movingTile, selectedTileNum);
                            SoundManager.playSound(3, 1, 0);
                        } else if (selectedBoardTileX != -1
                                && selectedBoardTileY != -1) {
                            b.addTile(movingTile, selectedBoardTileX,
                                    selectedBoardTileY);
                            SoundManager.playSound(3, 1, 0);
                        }
                    }
                    if (ge.getBoard().isValidPlacement()) {
                        Message msg = mHandler.obtainMessage();
                        Bundle bundle = new Bundle();
                        bundle.putBoolean("clickable", true);
                        msg.setData(bundle);
                        mHandler.sendMessage(msg);
                    } else {
                        Message msg = mHandler.obtainMessage();
                        Bundle bundle = new Bundle();
                        bundle.putBoolean("clickable", false);
                        msg.setData(bundle);
                        mHandler.sendMessage(msg);
                    }
                    undoMovingChanges();
                } else {
                    undoMovingChanges();
                }
                break;
            default:
                break;
            }
            prevEventX = eventX;
            prevEventY = eventY;
        }

        private void doDraw(Canvas canvas) {
            if (ge == null)
                return;


            Rect bRect = new Rect(0, 0, dims.getTotalWidth(),
                    dims.getScoreHeight() + dims.getBoardheight());
            Drawable drawable = getResources().getDrawable(R.drawable.board);
            drawable.setBounds(bRect);
            drawable.draw(canvas);


            Rect tRect = new Rect(0, dims.getScoreHeight()
                    + dims.getBoardheight(), dims.getTotalWidth(),
                    dims.getTotalHeight());
            canvas.drawRect(tRect, fillTrayPaint);

            int topHeight = dims.getScoreHeight() + dims.getBoardheight();
            int bottom = (dims.getTotalHeight() + 5)
                    - (dims.getTotalWidth() / Tray.TRAY_SIZE);
            Rect rect = new Rect(0, topHeight, dims.getTotalWidth(), bottom-7);
            Drawable drawableTray = getResources().getDrawable(
                    R.drawable.mainbg);
            drawableTray.setBounds(rect);
            drawableTray.draw(canvas);


            drawTray(canvas);
            drawBoard(canvas);
            // drawScore(canvas);
            drawMovingTile(canvas);
        }

        Tile t;

        private void drawMovingTile(Canvas canvas) {
            if (tileIsMoved) {
                tileTextPaint.setTextSize(defaultFontS * 2);


                drawTile(canvas, movingTileX - 2 * dims.getCellSize(),
                        movingTileY - 2 * dims.getCellSize(), movingTileX + 2
                                * dims.getCellSize(),
                        movingTileY + 2 * dims.getCellSize(),
                        Character.toString(movingTile.getLetter()), 1);

            }
        }

        // private void drawScore(Canvas canvas) {
        // }

        private void drawBoard(Canvas canvas) {
            int bHeight = dims.getBoardheight();

            int bWidth = bHeight;
            int sHeight = dims.getScoreHeight();
            int padding = dims.getPadding();

            int left = dims.getPadding() + (BOARD_SIZE / 2)
                    * dims.getCellSize();
            int top = dims.getScoreHeight() + (BOARD_SIZE / 2)
                    * dims.getCellSize();
            int bottom = 1 * dims.getCellSize() + top;
            int right = 1 * dims.getCellSize() + left;



            if (ge == null)
                return;

            Board b = ge.getBoard();
            TileStack[][] ts = b.getTilePlacement();
            for (int i = 0; i < ts.length; i++) {
                for (int j = 0; j < ts[i].length; j++) {
                    if (b.hasTile(i, j)) {
                        if (selectedBoardTileX == i && selectedBoardTileY == j)
                            tileFillPaint.setColor(Color.YELLOW);
                        else if (b.getTile(i, j).getAge() == b.getTurn())
                            tileFillPaint.setARGB(255, 160, 160, 200);
                        else
                            tileFillPaint
                                    .setColor(BoardView.STACK_COLOR[ts[i][j]
                                            .getNumTilesInStack() - 1]);
                        left = dims.getPadding() + j * dims.getCellSize();
                        right = left + dims.getCellSize();
                        top = dims.getScoreHeight() + i * dims.getCellSize();
                        bottom = top + dims.getCellSize();
                        tileTextPaint.setTextSize(2 * defaultFontS);
                        drawTile(canvas, left, top, right, bottom,
                                Character.toString(ts[i][j].getTop()
                                        .getLetter()), 0);
                        tileFillPaint.setColor(Color.WHITE);
                    }
                }
            }
        }

        private void drawTray(Canvas canvas) {
            // Draw the tray background
            Rect tileFillRect;
            tileFillRect = new Rect(0, (dims.getTotalHeight() - 8)
                    - (dims.getTotalWidth() / Tray.TRAY_SIZE),
                    dims.getTotalWidth(), dims.getTotalHeight());

            Drawable drawableTray = getResources().getDrawable(
                    R.drawable.bg_footer_tray);
            drawableTray.setBounds(tileFillRect);
            drawableTray.draw(canvas);

            // set text Size
            tileTextPaint.setTextSize(2 * defaultFontS);
            // fill the tray item
            int turn = ge.getPlayerTurn();
            Tray t = ge.getPlayer(turn).getTray();
            int tileSize = dims.getTotalWidth() / (Tray.TRAY_SIZE - 1);
            if (tileSize >= dims.getTrayHeight())
                tileSize = (4 * dims.getTrayHeight() / 5) - 5;
            int bot_border = 7;

            int space = (dims.getTotalWidth() - (tileSize * Tray.TRAY_SIZE))
                    / (Tray.TRAY_SIZE + 1);
            int reps = t.getNumUnusedTiles();
            tilesTray = new Rect[reps];
            for (int i = 0; i < reps; i++) {
                if (t.getTile(i) == null)
                    continue;

                if (i == 0) {
                    tilesTray[i] = drawTile(canvas, i * tileSize + (i + 1)
                            * space - bot_border, dims.getTotalHeight()
                            - tileSize - 2 * bot_border, i * tileSize + (i + 1)
                            * space + tileSize + bot_border,
                            dims.getTotalHeight() - bot_border,
                            t.getTileLetter(i), 0);

                } else if (i == 1) {
                    tilesTray[i] = drawTile(canvas, i * tileSize + (i + 1)
                            * space - bot_border, dims.getTotalHeight()
                            - tileSize - 2 * bot_border, i * tileSize + (i + 1)
                            * space + tileSize + bot_border,
                            dims.getTotalHeight() - bot_border,
                            t.getTileLetter(i), 0);
                } else if (i == 2) {
                    tilesTray[i] = drawTile(canvas, i * tileSize + (i + 1)
                            * space - bot_border, dims.getTotalHeight()
                            - tileSize - 2 * bot_border, i * tileSize + (i + 1)
                            * space + tileSize + bot_border,
                            dims.getTotalHeight() - bot_border,
                            t.getTileLetter(i), 0);
                } else if (i == 3) {
                    tilesTray[i] = drawTile(canvas, i * tileSize + (i + 1)
                            * space - bot_border, dims.getTotalHeight()
                            - tileSize - 2 * bot_border, i * tileSize + (i + 1)
                            * space + tileSize + bot_border,
                            dims.getTotalHeight() - bot_border,
                            t.getTileLetter(i), 0);
                } else if (i == 4) {
                    tilesTray[i] = drawTile(canvas, i * tileSize + (i + 1)
                            * space - bot_border, dims.getTotalHeight()
                            - tileSize - 2 * bot_border, i * tileSize + (i + 1)
                            * space + tileSize + bot_border,
                            dims.getTotalHeight() - bot_border,
                            t.getTileLetter(i), 0);
                } else if (i == 5) {
                    tilesTray[i] = drawTile(canvas, i * tileSize + (i + 1)
                            * space - bot_border, dims.getTotalHeight()
                            - tileSize - 2 * bot_border, i * tileSize + (i + 1)
                            * space + tileSize + bot_border,
                            dims.getTotalHeight() - bot_border,
                            t.getTileLetter(i), 0);
                } else if (i == 6) {
                    tilesTray[i] = drawTile(canvas, i * tileSize + (i + 1)
                            * space - bot_border, dims.getTotalHeight()
                            - tileSize - 2 * bot_border, i * tileSize + (i + 1)
                            * space + tileSize + bot_border,
                            dims.getTotalHeight() - bot_border,
                            t.getTileLetter(i), 0);
                } else {
                    tilesTray[i] = drawTile(canvas, i * tileSize + (i + 1)
                            * space, dims.getTotalHeight() - tileSize
                            - bot_border, i * tileSize + (i + 1) * space
                            + tileSize, dims.getTotalHeight() - bot_border,
                            t.getTileLetter(i), 0);
                }
                t.getTileLetter(i));
                tileFillPaint.setColor(Color.WHITE);
            }
        }

        private Rect drawTile(Canvas canvas, int left, int top, int right,
                int bottom, String text, int id) {

            Rect tileRect;
            tileRect = new Rect(left, top, right, bottom);

            // by ashwani
            Drawable drawableMain = getResources().getDrawable(
                    R.drawable.blankbtn);
            drawableMain.setBounds(tileRect);
            drawableMain.draw(canvas);
            Paint p = new Paint();
            Picture picture = new Picture();
            picture.draw(canvas);
            canvas.drawPicture(picture);

            );
            if (id == 0) {
                canvas.drawText(text, left + (right - left) / 2, bottom
                        - (bottom - top) / 5, tileTextPaint);
            } else {
                int k = 9;
                canvas.drawText(text, left + (right - left) / 2,
                        (bottom - (bottom - top) / 5) - 25, tileTextPaint);
                int i = 0;
            }

            // canvas.drawText(text, left + (right - left) / 2, bottom
            // - (bottom - top) / 5, tileTextPaint);

            return tileRect;
        }

        private void undoMovingChanges() {
            tileIsMoved = false;
            boardTileIsMoved = false;
            selectedTileNum = -1;
            selectedBoardTileX = -1;
            selectedBoardTileY = -1;
        }

        private int getMovingTileXPos(int x) {
            if (x < dims.getCellSize() / 2)
                return dims.getCellSize() / 2;
            else if (x > dims.getTotalWidth() - dims.getCellSize() / 2)
                return dims.getTotalWidth() - dims.getCellSize() / 2;
            else
                return x;
        }


        }

        private void handleTrayClick(int x, int y) {
            for (int i = 0; i < tilesTray.length; i++) {
                try {
                    if (tilesTray[i].contains(x, y))
                        selectedTileNum = i;
                } catch (NullPointerException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        private void calculateStackCoords(int x, int y) {
        }




        @Override
        public boolean onTouch(View v, MotionEvent event) {
            System.out.println(" on touch event");
            return false;
        }
    }

    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

        }
    };

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

        SurfaceHolder holder = getHolder();
        holder.addCallback(this);

        // endTurn=(ImageButton)findViewById(R.id.endturn_button_horizontal);
        thread = new DrawingThread(holder, handler);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        final float scale1 = getResources().getDisplayMetrics().density;
        defaultFontSize = (int) (MIN_FONT_DIPS * scale1 + 0.5f);
        thread.setDefaultFontSize(defaultFontSize);
        dimensions = calculateDimensions(getWidth(), getHeight());
        thread.setDimensions(dimensions);

        thread.setRunning(true);
        thread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        thread.setRunning(false);
        while (retry) {
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {

            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        System.out.println(" on touch event");
        int evt = event.getAction();
        int x = (int) event.getX();
        int y = (int) event.getY();
        thread.setEventInfo(evt, x, y);
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return true;
    }

    public void setEndTurn(Button end) {
        endTurn = end;
        endTurn.setClickable(false);
    }

    public void setSwitchMode(boolean b) {
        thread.setSwitchMode(b);
    }

    public Dimensions getDimensions() {
        return dimensions;
    }

    public void setGameEngine(GameEngine ge) {
        thread.setGameEngine(ge);
    }

    public void setPopupWindow(PopupWindow popUp) {
        thread.setPopupWindow(popUp);
    }

    private Dimensions calculateDimensions(int width, int height) {
        int cellSize, padding, top, bWidth, bHeight, scHeight, tHeight;
        int maxCellSize;

        Dimensions dims = new Dimensions();
        dims.setTotalWidth(width);
        dims.setTotalHeight(height);
        cellSize = width / BOARD_SIZE;
        maxCellSize = 3 * defaultFontSize;
        if (maxCellSize < cellSize)
            cellSize = maxCellSize;
        bWidth = BOARD_SIZE * cellSize;
        bHeight = bWidth;
        padding = (width - bWidth) / 2;
        scHeight = defaultFontSize * 2;
        tHeight = cellSize * 4;

        if (height >= bWidth + scHeight + tHeight) {
            top = (height - bWidth - scHeight - tHeight) / 2;
        } else {
            top = 0;
            tHeight = 4 * defaultFontSize;
            if (height - bHeight - tHeight > tHeight) {
                tHeight = height - bHeight - tHeight;
                scHeight = height - bHeight - tHeight;
            } else {
                scHeight = height - bHeight - tHeight;
            }
        }
        dims.setCellSize(cellSize);
        dims.setBoardheight(bHeight);
        dims.setPadding(padding);
        dims.setScoreHeight(1);
        dims.setTop(top);
        dims.setTrayHeight(tHeight);
        return dims;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        return false;
    }
}
4

1 回答 1

0

只需写下以下代码:

objectname.setBuiltInZoomControls(true);
于 2012-07-21T09:41:05.533 回答