我正在开发比赛应用程序。该应用程序已连接到Firebase实时数据库,该数据库被组织成一些子级列表,每个子级都有自己的字符串值,如下所示:
category1:
child1: "string"
child2: "string"
category2:
child3: "string"
child4: "string"
(etc.)
我正在尝试获取这些类别的名称,并将它们添加到我的布局之一的Spinner下拉菜单中。但是,当我测试此布局时,会发生一些奇怪的事情。如果点击微调按钮以打开下拉菜单,它将不断刷新自身(我可以看到它不断关闭并重新打开)。甚至更奇怪的是,有时,它只会显示两个字符串的列表(默认情况下我会添加),而上面的类别名称都不显示,而其他时候它将在列表中同时显示两个字符串。
无论我是否尝试从Firebase添加子名称字符串,刷新问题似乎都会发生。我知道发生这种情况的原因是Android Studio中的调试器窗口经常被垃圾邮件
D/ViewRootImpl@a8fa8f6[PopupWindow:d00794f]: Relayout returned: old=[286,729][962,1113] new=[286,729][962,1113] result=0x1 surface={valid=true 531823960064} changed=false
只要打开“微调器”下拉菜单(在两种情况下)。我尝试搜索该错误(全部或部分),但找不到与我要完成的任务完全相关的东西。
这是将列表添加到微调框的代码(打开“活动”时将调用此方法):
public void onOpen() {
// This is not the complete method, but the relevant portion of it
final List<String> categories = new ArrayList<>();
categories.add(selectionEmpty);
categories.add(selectionCreateNew);
dbh.dbref.child("users").child("a_users_uid_goes_here").child("flashcards").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
categories.add(child.getKey());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, categories);
setSelector.setAdapter(dataAdapter);
}
这是我分配给微调器的OnItemSelectedListener:
AdapterView.OnItemSelectedListener selectSet = new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long id) {
String selection = adapterView.getItemAtPosition(pos).toString();
if (selection.equals(selectionEmpty)) onOpen();
if (selection.equals(selectionCreateNew)) onCreateNewSet();
else onSelectSet(selection);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
};
onCreateNewSet()
和onSelectSet(String set)
当前是两个空方法。我认为这不会产生任何影响,但是以防万一,他们目前不会采取任何措施。 onOpen()
是上面的代码段。这是我第一次使用Spinner对象,而且一般来说我也是Android Studio的新手(使用了6个月),因此如果我只是缺少明显的代码行,我深表歉意。总结一下:最佳情况下,Spinner下拉列表应该显示两个预设字符串和数据库中的所有类别名称,并且只能打开一次。实际发生的情况是它不断重复关闭/打开,并且每隔打开一次仅显示数据库中的类别名称(但是预设字符串始终存在)。我非常感谢您的帮助!
如果有人需要,我可能会很快将遇到的问题链接到GIF。
更新:似乎只有在下拉菜单中选择了默认值(这是两个预设字符串之一)时,才会发生此刷新故障。如果我选择另一个,则不会发生此故障。仍然不确定为什么会这样。
第二次更新:我自己解决了这个问题,这是我很尴尬地犯的一个菜鸟错误。问题在于,在方法
onOpen()
中,我为Spinner设置了适配器,但是在Spinner的AdapterView.onItemSelectedListener
中,我再次调用了onOpen()
,这导致递归循环破坏了一切。解决方法是创建一个名为onOpen()
的onSelectNoSet()
复制方法,该方法除了未设置微调器的适配器之外,还执行了相同的操作,并让侦听器调用该方法而不是onOpen()
。TL; DR递归不好
最佳答案
第二次更新:我自己解决了这个问题,这是我很尴尬地犯的一个菜鸟错误。问题在于,在方法onOpen()
中,我为Spinner设置了适配器,但是在Spinner的AdapterView.onItemSelectedListener
中,我再次调用了onOpen()
,从而导致递归循环中断了所有工作。解决方法是创建一个称为onOpen()
的onSelectNoSet()
重复方法,该方法除了未设置微调器的适配器之外,还执行了相同的操作,并让侦听器调用该方法而不是onOpen()
。
TL; DR递归不好