在 LibGDX scene2d 中,更改选择框的项目后,它不再具有默认侦听器

In LibGDX scene2d, after changing the items of a selectbox, it no longer has a default listener

我不认为我的问题很难解决,但我已经搜索了一段时间,无法解决。

我有两个 scene2d SelectBox 小部件一个在另一个上面,在一个 table 的舞台上。我们称它们为 A 和 B。A 中的 select 决定了 B 中显示的列表。我在 A 上使用 ChangeListener 实现了这一点并且一切正常(这不是问题)。

但是,我的列表 A 变得非常长(500 多个项目)所以我想在它上面添加一个 TextField 来搜索和匹配字符串,用较短的列表替换旧的 A 列表,让您更容易找到所需的内容。这很好用,我在文本字段上使用 ChangeListener 来获取字符串,使用 for 循环将其与主字符串列表进行比较,然后使用 aList.setItems(); 将调整后的字符串添加到 SelectBox.列表显示(没有点击,所以我在 TextFieldChangeListener 中使用 aList.showList();)我认为这就是问题发生的地方 - 而不是点击,showList() 从别处调用。比方说我改变主意,想要 select 与 A 不同的项目,它将不再在单击时下拉菜单。但是,如果我更改搜索栏中的文本,它会显示列表。当列表显示时,我可以单击一个项目,它会正常隐藏。

这可能看起来有点令人困惑,所以这是代码(为清楚起见进行了编辑,所以如果缺少什么请告诉我)

SelectBox aSelect, bSelect;
TextField searchBar;
Stage stage;
Table table;
Skin skin;

ArrayList<String> completeAList;
ArrayList<String> abrevAList;

public chooseItemScreen()
{
    stage = new Stage(new ScreenViewport());
    skin = new Skin(Gdx.files.internal("uiskin.json"));
    table = new Table();
    table.setFillparent(true);

    completeAList = new ArrayList<String>;
    abrevAList = new ArrayList<String>;

    aSelect = new SelectBox(skin);
    //ItemList is a class with the list of strings as a static method
    completeAList = ItemList.getAList();
    aSelect.setItems(completeAList.toArray());

    //bSelect omitted as is same as A
    //aSelect changeListener also omitted as it is working fine

    searchBar = new TextField("", skin);
    searchBar.setMessageText("SEARCH LIST");

    searchPokemon.addListener(new ChangeListener() {
        @Override
        public void changed(ChangeEvent event, Actor actor) {
            updateASelect();
        }
    });

    table.add(searchBar);
    table.row();
    table.add(aList);

    stage.addActor(table);

    Gdx.input.setInputProcessor(stage);

}

private void updateAList()
{
    abrevAList.clear();
    aSelect.clearItems();
    aSelect.hideList()

    for (String string: completeAList)
    {
        if (string.toLowerCase().startsWith(searchBar.getText().toLowerCase()))
        {
            abrevAList.add(string);
        }
    }

    if (abrevAList.isEmpty())
    {
        abrevAList.add("NOT FOUND");
    }

    aSelect.setItems(abrevAList.toArray());

    //It's at this point where I am no longer to click on aSelect
    //I can still select an item from the drop down list, closing the list
    //it's just I can't show list by clicking on the widget after that

    aSelect.showList();
}

@Override
public void render(float delta) {
    Gdx.gl20.glClearColor(0,0,0,0);
    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);

    stage.act();
    stage.draw();

}

我添加了以下监听器来判断 selectBox 是否被点击(确实如此)。我给所有演员起了名字

    stage.getRoot().addCaptureListener(new InputListener() {
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            System.out.println(event.getTarget().getName());
            return false;
        }
    });

点击被识别,只是列表不显示。在我看来,同时调用showList()和更改列表是有问题的。

感谢任何帮助,如果您需要更多代码或任何其他信息,请告诉我。

谢谢

将选择框添加到 table 时为选择框设置固定大小,例如

table.add(selectBox).width(someValue);

table.add(selectBox).growX();

此外,在查看您的代码后,我建议您删除

    aSelect.clearItems();
    aSelect.hideList();

并使 ArrayList 成为 libgdx Array,这将使事情变得更容易,在使用“:”迭代时不会导致分配,并且在设置选择框的项目时不需要 .toArray() .您还可以使用 SelectBox 设置 SelectBox 类型,并且,您可以在同一行添加一行 table.add(something).row().

更改选择框单元格的大小后,您的代码在我这边工作得很好。