我有一个ExpandableListView
内的用户列表,现在我有2组列表,现在我正在尝试创建一个ArrayList
,我会在点击时添加数据用户,所以如果有2组学校,我点击每个学生,我应该在我的阵列中有2个位置,每个组包含其各自的用户,我的问题是,我的阵列有2个位置,但它不是分开学生:
我想要的是:
学校A:
student1已选中
STUDENT2
student3已选中
学校B:
student4
student5选择
导致:
[0] - >学生1,3 [1] - >学生5
这是我到目前为止所尝试的内容:
mGpsEscolas = new GPSEscolas();
mArrayEscolas = new ArrayList<GPSEscolas>();
aMap = new HashMap<String, GPSEscolas>();
ExpandList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(final ExpandableListView parent, View v, final int groupPosition, final int childPosition, final long id) {
ExpAdapter.setClicked(groupPosition, childPosition);
index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));
parent.setItemChecked(index, true);
parent.setSelectedChild(groupPosition, childPosition, true);
parent.getChildAt(index);
IdAlunos = String.valueOf(mMainRest.mArrayList.get(groupPosition).getalunos().get(childPosition).getId_aluno());
IdEscola = String.valueOf(mMainRest.mArrayList.get(groupPosition).getId_escola());
ids_alunos.add(IdAlunos);
notificar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int groupCount = ExpandList.getExpandableListAdapter().getGroupCount();
for (int group = 1; group <= groupCount; group++) {
int gcount = ExpandList.getExpandableListAdapter().getChildrenCount(groupPosition);
mArrayEscolas = new ArrayList<GPSEscolas>();
for (int child = 1; child <= gcount; child++) {
mGpsEscolas.setIds_alunos(String.valueOf(IdAlunos).substring(1));
mGpsEscolas.setId_escola(Integer.valueOf(IdEscola));
mGpsEscolas.setLatitude(latitudeEscola);
mGpsEscolas.setLongitude(longitudeEscola);
mGpsEscolas.setDistancia(mMainRest.RaioEscola);
mArrayEscolas.add(mGpsEscolas);
if (ExpAdapter.isChildSelectable(groupPosition, childPosition)) {
aMap.put(ExpandList.getExpandableListAdapter().getChildId(group, child), mArrayEscolas);
}
}
}
}
});
return false;
}
});
答案 0 :(得分:4)
一个简单的解决方案是创建一个新的类SelectableObject
:
class SelectableObject<T>
{
boolean sel; T obj;
public SelectableObject<T>(T obj) { this.obj=obj; this.sel=false; }
public void select() { this.sel=true; }
public void deselect() { this.sel=false; }
public boolean isSelected() { return this.sel; }
public T getObject() { return this.obj; }
}
然后像这样创建ExpandableListView
public void setChildData()
{
ArrayList<SelectableObject<GPSEscolas>> child
= new ArrayList<SelectableObject<GPSEscolas>>();
child.add(new SelectableObject<GPSEscolas>(new GPSEscolas(..)));
..
childItems.add(child);
}
然后我们需要调用onSelect
侦听器函数调用select
函数
mExpandableList.setOnChildClickListener(new OnChildClickListener() {
@Override public boolean onChildClick(ExpandableListView parent,
View v,int groupPosition, int childPosition, long id) {
SelectableObject<GPSEscolas> item = (SelectableObject<GPSEscolas>)
parent.getExpandableListAdapter().getChild(groupPosition,childPosition);
if(!item.isSelected()) item.select();
else item.deselect();
..
})
然后我们可以查询这样的选定项目
public static ArrayList<GPSEscolas> getSelectedChildren(ExpandableListView listView)
{
ArrayList<GPSEscolas> list = new ArrayList<GPSEscolas>();
int count = listView.getGroupCount();
for (int group = 1; group <= count; group++)
{
int gcount = listView.getChildrenCount(position);
for (int child = 1; child <= gcount; child++)
{
SelectableObject<GPSEscolas> item = (SelectableObject<GPSEscolas>)
listView.getExpandableListAdapter().getChild(groupPosition,childPosition);
// Here is where you can see the solution beauty
if (item.isSelected())
{
list.add(item.getObject());
}
}
}
return list;
}
答案 1 :(得分:2)
还有一条路要走。通过监听此事件,您可以创建Map<group,List<child>> selected items
并以相同的方式将项添加到此列表,而不是创建包装器对象:
mExpandableList.setOnChildClickListener(new OnChildClickListener() {
@Override public boolean onChildClick(ExpandableListView parent,
View v,int groupPosition, int childPosition, long id) {
//toggle selections code here
}
所以这里有重要的部分:(和完整的工作github repo)
@Override
protected void onCreate(Bundle savedInstanceState) {
...// some init part
final MyAdapter adapter = new MyAdapter(schools, students);
listView.setAdapter(adapter);
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent,
View v, int groupPosition, int childPosition, long id) {
adapter.toggleSelection(groupPosition, childPosition);
adapter.notifyDataSetInvalidated();
return false;
}
});
}
我们有几个选项可以放置这些选定的项目,但在我的项目中,我在自定义适配器类中使用它。客户端适配器并不是真正的需要,并且可以在Activity中放置Map<G, List<C>> selectedItems;
和相关函数(toggleSelection,isSelected,getSelectedItems),但我们仍然需要突出显示所选的销售,因此适配器通常是最佳位置把它。
private class MyAdapter<G, C> extends BaseExpandableListAdapter {
private List<G> groups;
private Map<G, List<C>> childMap;
private Map<G, List<C>> selectedItems;
public MyAdapter(List<G> groups, Map<G, List<C>> childMap){
this.groups = groups;
this.childMap = childMap;
this.selectedItems = new HashMap<>();
}
public boolean isSelected(int groupPosition, int childPosition){
G group = groups.get(groupPosition);
// getChild is adapter Fn and is the same as
// G group = groups.get(groupPosition)
// C child = childMap.get(group).get(childPosition);
C child = getChild(groupPosition, childPosition);
List<C> sel = selectedItems.get(group);
return sel != null && sel.contains(child);
}
public void toggleSelection(int groupPosition, int childPosition){
G group = groups.get(groupPosition);
C child = getChild(groupPosition,childPosition);
List<C> sel = selectedItems.get(group);
if (sel == null){
sel = new ArrayList<>(); // Lasy arrays creation
//can init all arrays in constructor and never check for nulls
selectedItems.put(group, sel);
}
if (sel.contains(child)) sel.remove(child);
else sel.add(child);
}
... // Adapter fns can find in git repo
将结果地图转换为List将是一项简单的任务:
private ArrayList<String> selectedAsList(Map<String, List<String>> selectedItems){
ArrayList<String> result = new ArrayList<>();
for(List<String> students: selectedItems.values())
result.addAll(students);
return result;
}
或类似的东西。
PS。你也可以玩Map<group,List<child>>
。它几乎可以
您想要的数据结构。如果您的组数据中没有重复项,则可以使用2个阵列,也可以只使用1个阵列。你可以控制它,限制选择的数量等等......