Менеджер раскладки BoxLayout (X_AXIS_SCROLLING) для Codename One - PullRequest
0 голосов
/ 21 октября 2018

Примечание для читателей: этот вопрос относится только к кодовому имени 1.

Мой пример использования - иметь одну или несколько горизонтальных прокручиваемых полос с кнопками.

Мне нужен менеджер компоновки, который:

  • размещает все Компоненты по оси X;
  • дает каждому Компоненту свой предпочтительный размер;
  • если горизонтального пространства достаточно, он действует точно так же, как BoxLayout(X_AXIS_NO_GROW);
  • , если горизонтального пространства недостаточно, он позволяет горизонтальную прокрутку, чтобы увидеть все компоненты;
  • в последнемВ этом случае добавляется небольшая стрелка слева и справа, указывающая, что прокрутка возможна.

Например, следующий код создает следующий снимок экрана:

    Form hi = new Form("BoxLayout X scrolling", BoxLayout.y());

    Container exampleCnt = new Container();
    exampleCnt.setLayout(new BoxLayout(BoxLayout.X_AXIS_NO_GROW));

    for (int i=0; i<=10; i++) {
        int j = i; // for lambda expression
        Button button = new Button("Button " + i);
        button.addActionListener(l -> {Log.p("Button " + j + " tapped");});
        exampleCnt.add(button);
    }

    hi.add(exampleCnt);
    hi.show();

enter image description here

Вместо этого мне нужно что-то вроде следующих скриншотов.Я предполагаю горизонтальную прокрутку панели кнопок (exampleCnt) пальцем.Приложение должно быть достаточно умным, чтобы не путать нажатие кнопки с горизонтальным пролистыванием для прокрутки кнопок:

enter image description here

enter image description here

enter image description here

enter image description here

1 Ответ

0 голосов
/ 21 октября 2018

Есть несколько подходов к этому, и у каждого из них есть свои преимущества / недостатки.Давайте начнем с вопроса:

  • Должны ли кнопки со стрелками нажиматься?
  • Должны ли они рисовать как наложение (вы увидите кнопку под ними, когда они появятся) или должныони действуют как отдельные компоненты?

На основе ваших ответов вы можете выбрать один из следующих вариантов.

Встроенная поддержка прокрутки

Это будетсгенерировать что-то, что будет отображаться как наложение и не будет кликабельным, так как прокрутка предполагает интерфейс в стиле полосы прокрутки, но также должна работать в этом случае.

Вам может потребоваться вызвать setScrollVisible(true) на Container.

Затем переопределить в Container:

protected void paintScrollbarX(Graphics g) {
    float scrollW = getScrollDimension().getWidth();
    float block = ((float) getWidth()) / scrollW;
    float offset;
    if(getScrollX() + getWidth() == scrollW) {
        // normalize the offset to avoid rounding errors to the bottom of the screen
        offset = 1 - block;
    } else {
        offset = (((float) getScrollX() + getWidth()) / scrollW) - block;
    }
    // here paint the arrows to the left/right based on the values
}

Использовать оболочку

С помощью обертки вы можете просто использовать кнопки для обозначения стрелок.Вы можете разместить их либо в многослойном макете для создания эффекта наложения, либо по бокам для создания разделения, например, это приведет к появлению отдельных кнопок:

BorderLayout wrap = BorderLayout.centerEastWest(scrollableCnt, right, left);

Это приведет к наложению:

BorderLayout border = BorderLayout.centerEastWest(null, right, left);
LayeredLayout wrap = LayeredLayout(scrollableCnt, border);

Чтобы сделать это, мы хотели бы скрыть / показать компоненты на основе прокрутки.isScrollableX() вернет false для не прокручиваемого компонента, поэтому:

if(scrollableCnt.isScrollableX()) {
    left.setVisible(false);
    scrollableCnt.addScrollListener((scrollX, scrollY, oldscrollX, oldscrollY) -> {
        left.setVisible(scrollX > 0);
        // not 100% sure about this line but it should be something close to this
        right.setVisible(scrollX < getScrollDimension().getWidth() - scrollableCnt.getWidth());
    });
} else {
    right.setVisible(false);
    left.setVisible(false);
}
...