ExpandableListView 不调用 OnItemSelectedListener
ExpandableListView does not call OnItemSelectedListener
我在我的自定义 ExpandableListView
中设置了一个 OnItemSelectedListener
:
setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.debug(TAG, "item selected");
// do stuff
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
Log.debug(TAG, "nothing selected");
// do stuff
}
});
永远不会调用此侦听器,无论是通过触摸项目还是调用 setSelected(int)
或 setSelectedGroup(int)
。
还有其他问答可以追溯到 2010 年,关于 OnItemSelectedListener
不能与 ListView
一起工作。我找不到真正解释如何让它工作的人。常见的答案是改用点击监听器。我想尽可能避免这种情况,因为我需要知道何时没有选择任何内容(即列表为空)并且我想利用 OnItemSelectedListener#onItemSelected(...)
:
的这个特性
This callback is invoked only when the newly selected position is different from the previously selected position or if there was no selected item.
我可以通过其他方式实现这两个目标,但如果 OnItemSelectedListener
有效,那就更好了。
编辑: ExpandableListView
似乎在项目选择方面完全被破坏了。在点击侦听器中调用时,此代码段将所选项目记录为 -1:
setSelection(0);
setSelectedGroup(0);
Log.debug(TAG, "selected item: " + getSelectedItemPosition());
请使用以下适合您的方法之一\
exlvReportData.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
return false;
}
});
// Listview Group expanded listener
exlvReportData.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
//Toast.makeText(getApplicationContext(),
//listDataHeader.get(groupPosition) + " Expanded",
//Toast.LENGTH_SHORT).show();
}
});
// Listview Group collasped listener
exlvReportData.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
//Toast.makeText(getApplicationContext(),
//listDataHeader.get(groupPosition) + " Collapsed",
// Toast.LENGTH_SHORT).show();
}
});
// Listview on child click listener
exlvReportData.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
// Toast.makeText(
// getApplicationContext(),
// listDataHeader.get(groupPosition)
// + " : "
// + listDataChild.get(
// listDataHeader.get(groupPosition)).get(
// childPosition), Toast.LENGTH_SHORT)
// .show();
return false;
}
});
如有任何问题,请随时发表评论
使用点击侦听器不仅仅是一种懒惰的解决方法。由于一些糟糕的设计决策,它是唯一的选择。 blog post from 2008 解释了为什么 OnItemSelectedListener
不起作用:
In touch mode, there is no focus and no selection. Any selected item in a list of [sic] in a grid becomes unselected as soon as the user enters touch mode.
继续:
The relationship between touch mode, selection, and focus means you must not rely on selection and/or focus to exist in your application. A very common problem with new Android developers is to rely on ListView.getSelectedItemPosition()
. In touch mode, this method will return INVALID_POSITION
.
理由如下:
Imagine a simple application . . . that shows a list of text items. The user can freely navigate through the list using the trackball and they can also scroll and fling the list using their finger. The issue in this scenario is the selection. If I select an item at the top of the list and then fling the list towards the bottom, what should happen to the selection? Should it remain on the item and scroll off the screen? In this case, what would happen if I then decide to move the selection with the trackball? Or worse, if I press the trackball to act upon the currently selected item, which is not shown on screen anymore. After careful considerations, we decided to remove the selection altogether.
在回答这些问题时,Android 开发人员忽略了其他 UI 工具包和数十年用户经验建立的约定。滚动列表时,选择是否应保留在项目上? 是的,当然应该! 如果移动选择会发生什么? 视图将滚动到新选择。 如果您按下轨迹球? 根据当前选择操作!
他们的 "careful considerations" 显然也没有包括将这些重要信息放在哪里。这属于 ListView
的文档,而不属于博客 post。
我在我的自定义 ExpandableListView
中设置了一个 OnItemSelectedListener
:
setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.debug(TAG, "item selected");
// do stuff
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
Log.debug(TAG, "nothing selected");
// do stuff
}
});
永远不会调用此侦听器,无论是通过触摸项目还是调用 setSelected(int)
或 setSelectedGroup(int)
。
还有其他问答可以追溯到 2010 年,关于 OnItemSelectedListener
不能与 ListView
一起工作。我找不到真正解释如何让它工作的人。常见的答案是改用点击监听器。我想尽可能避免这种情况,因为我需要知道何时没有选择任何内容(即列表为空)并且我想利用 OnItemSelectedListener#onItemSelected(...)
:
This callback is invoked only when the newly selected position is different from the previously selected position or if there was no selected item.
我可以通过其他方式实现这两个目标,但如果 OnItemSelectedListener
有效,那就更好了。
编辑: ExpandableListView
似乎在项目选择方面完全被破坏了。在点击侦听器中调用时,此代码段将所选项目记录为 -1:
setSelection(0);
setSelectedGroup(0);
Log.debug(TAG, "selected item: " + getSelectedItemPosition());
请使用以下适合您的方法之一\
exlvReportData.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
return false;
}
});
// Listview Group expanded listener
exlvReportData.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
//Toast.makeText(getApplicationContext(),
//listDataHeader.get(groupPosition) + " Expanded",
//Toast.LENGTH_SHORT).show();
}
});
// Listview Group collasped listener
exlvReportData.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
//Toast.makeText(getApplicationContext(),
//listDataHeader.get(groupPosition) + " Collapsed",
// Toast.LENGTH_SHORT).show();
}
});
// Listview on child click listener
exlvReportData.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
// Toast.makeText(
// getApplicationContext(),
// listDataHeader.get(groupPosition)
// + " : "
// + listDataChild.get(
// listDataHeader.get(groupPosition)).get(
// childPosition), Toast.LENGTH_SHORT)
// .show();
return false;
}
});
如有任何问题,请随时发表评论
使用点击侦听器不仅仅是一种懒惰的解决方法。由于一些糟糕的设计决策,它是唯一的选择。 blog post from 2008 解释了为什么 OnItemSelectedListener
不起作用:
In touch mode, there is no focus and no selection. Any selected item in a list of [sic] in a grid becomes unselected as soon as the user enters touch mode.
继续:
The relationship between touch mode, selection, and focus means you must not rely on selection and/or focus to exist in your application. A very common problem with new Android developers is to rely on
ListView.getSelectedItemPosition()
. In touch mode, this method will returnINVALID_POSITION
.
理由如下:
Imagine a simple application . . . that shows a list of text items. The user can freely navigate through the list using the trackball and they can also scroll and fling the list using their finger. The issue in this scenario is the selection. If I select an item at the top of the list and then fling the list towards the bottom, what should happen to the selection? Should it remain on the item and scroll off the screen? In this case, what would happen if I then decide to move the selection with the trackball? Or worse, if I press the trackball to act upon the currently selected item, which is not shown on screen anymore. After careful considerations, we decided to remove the selection altogether.
他们的 "careful considerations" 显然也没有包括将这些重要信息放在哪里。这属于 ListView
的文档,而不属于博客 post。