BlackBerry - TouchEvent на нескольких менеджерах - PullRequest
1 голос
/ 09 апреля 2010

Я новичок в разработке приложений BlackBerry. Вот мой вопрос: я использую два вертикальных менеджера поля "layout" и "manager" в своем приложении. В макете есть три пользовательских поля кнопок, а макет находится внутри менеджера.

Я не могу реализовать сенсорное событие, вот мой код:

public class MenuScreen extends MainScreen {
    public MenuScreen() {
        super(Screen.DEFAULT_CLOSE);
        Bitmap menuBackgroundImage = Bitmap
                .getBitmapResource("com/greetings/Images/MenuBackground.jpg");
        final VerticalFieldManager layout = new VerticalFieldManager() {
            public boolean touchEvent(TouchEvent message) {
                int x = message.getGlobalX(1);
                int y = message.getGlobalY(1);
                if (getExtent().contains(x, y)) {
                    int fieldI = getFieldAtLocation(x, y);
                    Field field = getField(fieldI);
                    field.setFocus();
                    return super.touchEvent(message);
                }
                return false;
            }
        };
        ButtonField categories = new ButtonField("Categories") {
            public void run() {
                Dialog.alert("one");
            }
            public boolean touchEvent(TouchEvent message) {
                int x = message.getX(1);
                int y = message.getY(1);
                int w = getWidth();
                int h = getHeight();
                if (x >= 0 && x <= w && y >= 0 && y <= h) {
                    switch (message.getEvent()) {
                    case TouchEvent.DOWN:
                        setFocus();
                        return true;
                    case TouchEvent.UNCLICK:
                        run();
                        return true;
                    }
                }
                return false;
            }
        };
        ButtonField help = new ButtonField("Help") {
            public void run() {
                Dialog.alert("help");
            }
            public boolean touchEvent(TouchEvent message) {
                int x = message.getX(1);
                int y = message.getY(1);
                int w = getWidth();
                int h = getHeight();
                if (x >= 0 && x <= w && y >= 0 && y <= h) {
                    switch (message.getEvent()) {
                    case TouchEvent.DOWN:
                        setFocus();
                        return true;
                    case TouchEvent.UNCLICK:
                        run();
                        return true;
                    }
                }
                return false;
            }
        };
        ButtonField developer = new ButtonField("Developer") {
            public void run() {
                Dialog.alert("Developer");
            }
            public boolean touchEvent(TouchEvent message) {
                int x = message.getX(1);
                int y = message.getY(1);
                int w = getWidth();
                int h = getHeight();
                if (x >= 0 && x <= w && y >= 0 && y <= h) {
                    switch (message.getEvent()) {
                    case TouchEvent.DOWN:
                        setFocus();
                        return true;
                    case TouchEvent.UNCLICK:
                        run();
                        return true;
                    }
                }
                return false;
            }
        };
        layout.add(categories);
        layout.add(help);
        layout.add(developer);
        VerticalFieldManager manager = new VerticalFieldManager() {
            protected void sublayout(int width, int height) {
                width = Display.getWidth();
                height = Display.getHeight();
                super.sublayout(width, height);
                setPositionChild(layout, width - 245, height - 350);
                setExtent(width, height);
            }
        };
        manager.setBackground(BackgroundFactory
                .createBitmapBackground(menuBackgroundImage));
        manager.add(layout);
        add(manager);
    }
}

1 Ответ

1 голос
/ 12 апреля 2010

Вот несколько предложений:

  • использовать стиль Button.CONSUME_CLICK
  • если есть способ, используйте FieldChangeListeners вместо сенсорных событий (для совместимости и простоты)
  • взгляните на Как - реализовать расширенные кнопки, поля и менеджеры
  • для того, чтобы менеджер размера не только устанавливал значение в подслое, но и переопределял getPrefferredWidth / Height
  • объявлять поля вне методов, так как они будут доступны из других методов

Этот менеджер должен быть любого размера и центрировать дочерние поля по вертикали и горизонтали:

class SizableVerticalButtonFieldSet extends Manager {
    int mWidth = 0;
    int mHeight = 0;

    public SizableVerticalButtonFieldSet(int width, int height) {
        this(width, height, Field.FIELD_HCENTER);
    }

    public SizableVerticalButtonFieldSet(int width, int height, long style) {
        super(style);
        mWidth = width;
        mHeight = height;
    }

    public int getPreferredWidth() {
        return mWidth;
    }

    public int getPreferredHeight() {
        return mHeight;
    }

    protected void sublayout(int width, int height) {
        width = getPreferredWidth();
        height = getPreferredHeight();

        int numChildren = this.getFieldCount();
        int prevTopMargin = 0;
        int usedHeight = 0;
        // calculate start y
        for (int i = 0; i < numChildren; i++) {

            Field currentField = getField(i);
            usedHeight += Math.max(prevTopMargin, currentField
                    .getMarginBottom());
            usedHeight += currentField.getHeight();
            prevTopMargin = currentField.getMarginBottom();
        }

        int x;
        int y = (height - usedHeight) >> 1;
        for (int i = 0; i < numChildren; i++) {

            Field currentField = getField(i);
            int currentPreferredWidth = currentField.getPreferredWidth()
                    + getBorderWidth(currentField);
            if (currentPreferredWidth < width) {
                int newPadding = (width - currentPreferredWidth) / 2;
                currentField
                        .setPadding(currentField.getPaddingTop(), newPadding,
                                currentField.getPaddingBottom(), newPadding);
            }
            layoutChild(currentField, width, height);

            y += Math.max(prevTopMargin, currentField.getMarginBottom());
            x = (width - currentField.getWidth()) / 2;
            setPositionChild(currentField, x, y);
            y += currentField.getHeight();
            prevTopMargin = currentField.getMarginBottom();
        }
        setExtent(width, height);
    }

    protected boolean navigationMovement(int dx, int dy, 
        int status, int time) {
        int focusIndex = getFieldWithFocusIndex();
        if (dx < 0 && focusIndex == 0) {
            // we cannot go left
            return true;
        }
        if (dx > 0 && focusIndex == getFieldCount() - 1) {
            // we cannot go right
            return true;
        }
        return super.navigationMovement(dx, dy, status, time);
    }

    public static int getBorderWidth(Field field) {
        int width = 0;

        // #ifdef VER_4.1.0 | VER_4.2.0 | VER_4.2.1 | VER_4.3.0 | VER_4.5.0
        width = field.getWidth() - field.getContentWidth()
                - field.getPaddingLeft() - field.getPaddingRight();
        // #else
        Border border = field.getBorder();
        if (border != null) {
            width = border.getLeft() + border.getRight();
        }
        // #endif
        return width;
    }
}

альтернативный текст http://img138.imageshack.us/img138/462/layoutbs.jpg

А это пример использования:

class MenuScreen extends MainScreen {
    VerticalFieldManager layout;
    ButtonField categories;
    ButtonField help;
    ButtonField developer;
    SizableVerticalButtonFieldSet manager;

    public MenuScreen() {
        super(DEFAULT_CLOSE);

        // generate background (for test only)
        int fWidth = Display.getWidth();
        int fHeight = Display.getHeight();
        Bitmap menuBackgroundImage = new Bitmap(fWidth, fHeight);
        Graphics g = Graphics.create(menuBackgroundImage);
        g.setColor(Color.GREEN);
        g.fillRect(0, 0, fWidth, fHeight);
        g.setColor(Color.GOLD);
        Font f = getFont().derive(Font.BOLD, 18);
        g.setFont(f);
        String text = "THIS IS A BACKGROUND";
        int tWidth = f.getAdvance(text);
        int tHeight = f.getHeight();
        int tX = (fWidth - tWidth) >> 1;
        int tY = (fHeight - tHeight) >> 1;
        g.drawText(text, tX, tY, DrawStyle.HCENTER | DrawStyle.VCENTER);

        layout = new VerticalFieldManager();

        // don't forget to set ButtonField.CONSUME_CLICK style
        categories = new ButtonField("Categories", ButtonField.CONSUME_CLICK);
        // use FieldChangeListener instead of touch events
        categories.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
                Dialog.alert("one");
            }
        });

        help = new ButtonField("Help", ButtonField.CONSUME_CLICK);
        help.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
                Dialog.alert("help");
            }
        });

        developer = new ButtonField("Developer", ButtonField.CONSUME_CLICK);
        developer.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
                Dialog.alert("Developer");
            }
        });
        layout.add(categories);
        layout.add(help);
        layout.add(developer);

        // if you need to set size of manager, better use manager extantion
        // use Display.getWidth(), Display.getHeight() for screen size manager
        manager = new SizableVerticalButtonFieldSet(fWidth, fHeight);
        manager.setBackground(BackgroundFactory
                .createBitmapBackground(menuBackgroundImage));
        manager.add(layout);
        add(manager);
    }
}
...