2

我有一个 ScrollPane,它在一个组中水平对齐了多个图像。我需要的是水平滚动,以在滚动时“捕捉”到图像,而不仅仅是滚动到所需的任何数量。所以在任何滑动之后,滚动应该停止以适应整个图像而不是半个图像。主要是每个图像宽度等于滚动窗格宽度。知道如何使用 libgdx ScrollPane 实现这一目标吗?

这是一个示例代码:

Image imgWhite = new Image(white);
imgWhite.setSize(width, height);
imgWhite.setPosition(0, 0);

Image imgYellow = new Image(white);
imgYellow.setColor(Color.YELLOW);
imgYellow.setSize(width, height);
imgYellow.setPosition(width, 0);

Image imgGreen = new Image(white);
imgGreen.setColor(Color.GREEN);
imgGreen.setSize(width, height);
imgGreen.setPosition(2*width, 0);

Group grp = new Group();
grp.addActor(imgWhite);
grp.addActor(imgGreen);
grp.addActor(imgYellow);
grp.setSize(3*width, height);

ScrollPane scrollPane = new ScrollPane(grp);
scrollPane.setSize(width, height);
4

1 回答 1

1

使用PagedScrollPane(调用addPage添加图像):

package com.your.package;

import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.utils.Array;
import com.esotericsoftware.tablelayout.Cell;

public class PagedScrollPane extends ScrollPane {

    private boolean wasPanDragFling = false;

    public static interface ScrollRunnable
    {
        public void run(Actor scrolledTo);
    }

    private Table content;
    private float pageSpace;
    private ScrollRunnable onScroll;

    public PagedScrollPane (float pageSpace) {
        super(null);
        setup(pageSpace);
    }

    public PagedScrollPane (Skin skin, float pageSpace) {
        super(null, skin);
        setup(pageSpace);
    }

    public PagedScrollPane (Skin skin, String styleName, float pageSpace) {
        super(null, skin, styleName);
        setup(pageSpace);
    }

    public PagedScrollPane (Actor widget, ScrollPaneStyle style, float pageSpace) {
        super(null, style);
        setup(pageSpace);
    }

    public void setOnScroll(ScrollRunnable onScroll)
    {
        this.onScroll = onScroll;
    }

    private void setup(float pageSpace) {
        this.pageSpace = pageSpace;
        this.onScroll = null;

        content = new Table();
        content.defaults().space(pageSpace);
        super.setWidget(content);
    }

    public void addPages (Actor... pages) {
        for (Actor page : pages) {
            content.add(page).expandY().fillY();
        }
    }

    public Cell addPage (Actor page) {
        return content.add(page).expandY().fillY();
    }

    @Override
    public void act (float delta) {
        super.act(delta);
        if (wasPanDragFling && !isPanning() && !isDragging() && !isFlinging()) {
            wasPanDragFling = false;
            scrollToPage();
        } else {
            if (isPanning() || isDragging() || isFlinging()) {
                wasPanDragFling = true;
            }
        }
    }

    @Override
    public void setWidget (Actor widget)
    {
        //
    }

    public void setPageSpacing (float pageSpacing) {
        if (content != null) {
            content.defaults().space(pageSpacing);
            for (@SuppressWarnings("rawtypes") Cell cell : content.getCells()) {
                cell.space(pageSpacing);
            }
            content.invalidate();
        }
    }

    private void scrollToPage () {
        final float width = getWidth();
        final float scrollX = getScrollX() + getWidth() / 2f;

        Array<Actor> pages = content.getChildren();
        if (pages.size > 0) {
            for (Actor a : pages) {
                float pageX = a.getX();
                float pageWidth = a.getWidth();

                if (scrollX >= pageX - pageWidth && scrollX < pageX + pageWidth)
                {
                    setScrollX(pageX - (width - pageWidth) / 2f);
                    if (onScroll != null)
                    {
                        onScroll.run(a);
                    }
                    break;
                }
            }
        }
    }

    public void scrollTo(Actor listenerActor)
    {
        float pageX = listenerActor.getX();
        float pageWidth = listenerActor.getWidth();
        final float width = getWidth();

        setScrollX(pageX - (width - pageWidth) / 2f);
    }

    public void addEmptyPage(float offset)
    {
        content.add().minWidth(offset);
    }
}

此外,它具有setOnScroll允许在将窗格滚动到某个图像后设置回调的方法。

编辑:修改scrollToPage()方法中的条件以避免盲点(滚动永远不会捕捉到页面)。

于 2013-12-23T00:05:37.893 回答