【问题标题】:How to store selected items of an ExpandableListView in an ArrayList如何将 ExpandableListView 的选定项目存储在 ArrayList 中
【发布时间】:2023-03-19 19:50:01
【问题描述】:

我在 ExpandableListView 中有一个用户列表,现在我有 2 组列表,现在我正在尝试创建一个 ArrayList,它将在我单击用户时添加数据,所以如果有2组学校,我点击每一个学生我的数组中应该有2个位置,每个组包含其各自的用户,我的问题是,我的数组有2个位置,但它没有分隔学生:

我想要的是这个:

学校 A:

学生1被选中

学生2

学生3被选中

学校 B:

学生4

学生5被选中

导致:

[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;
    }
});

【问题讨论】:

  • 您是否尝试过使用自定义 ExpandableListAdapter?跟踪所有内容可能更容易,包括“onChecked”侦听器以及附加到适配器的 ArrayList 对象。网上有不少例子:这是适配器的YouTube视频youtu.be/-tAH1hW_tYc
  • @c0d3blooded 我正在使用自定义 ExpandableListAdapter
  • 您需要在 GPSEscolas(parent) 模型类中创建学生(子)模型类的数组列表,并在单击或选择时管理一些布尔值。请关注此javacodegeeks.com/2013/06/…。如果您需要进一步的帮助,请告诉我。

标签: java android arrays multidimensional-array arraylist


【解决方案1】:

一个简单的解决方案是创建一个新类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;
}

【讨论】:

  • 感谢您的帮助,但我在实现您的代码时遇到了一些问题,例如在 getAllChildrenMap 函数中,“位置”在哪里定义? isSelected 和 getObject 方法也一样
  • 另外,当我点击一个孩子时出现错误,java.lang.Integer 无法转换为 com.clickpegue.models.SelectableObject
  • @WARpoluido 修复了onClick,添加了getSelectedChildren
  • @WARpoluido 修复了代码,看来你必须使用适配器来获取子对象
  • @WARpoluido 还有其他一些技术上更好的解决方案,但我认为它会使它的使用更加复杂,简化使用带来更高的可读性和可维护性
【解决方案2】:

还有一条路要走。您可以创建 Map&lt;group,List&lt;child&gt;&gt; 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;
        }
    });
}

我们有几个选项可以放置此类选定的项目映射,但在我的项目中,我在自定义适配器类中使用它。没有真正需要custome adapter,可以将Map&lt;G, List&lt;C&gt;&gt; selectedItems;和相关函数(toggleSelection、isSelected、getSelectedItems)放在Activity中,但是我们仍然需要高亮selected sell,所以adapter通常是最好的放置位置.

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 

将结果 Map 转换为 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&lt;group,List&lt;child&gt;&gt;。它几乎可以是任何 你想要的数据结构。如果您的组数据中没有重复项,则 2 个数组或可能只有 1 个单个数组。你可以控制它,限制选择的数量等等......

【讨论】:

  • 你有什么教程可以列出这个列表吗?我需要做这样的事情
猜你喜欢
  • 1970-01-01
  • 2018-02-06
  • 2017-02-07
  • 2018-02-07
  • 2017-04-28
  • 2015-07-26
  • 2015-02-02
  • 2017-12-21
  • 2016-04-04
相关资源
最近更新 更多