热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

AndroidExpandableListView长按事件的完美解决办法

本篇文章是对Android中ExpandableListView长按事件的解决方法进行了详细的分析介绍,需要的朋友参考下
关于ExpandableListView长按事件处理,网上很多都是使用将上下文菜单注册到ExpandableListView上实现长按事件。

这样做弊端显而易见,不够灵活,不能分别对父项、子项、父项之间、子项之间弹出内容做区分。
下面来说我的解决方法,方法有点投机取巧。首先说明一点,使用我这种方法必须使用自定义的BaseExpandableListAdapter,至于为什么,具体后面讲到。

ExpandableListView本身有继承自AdapterView的setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener)方法。
实现监听器:
代码如下:

/**
  * 长按邮箱快捷选项
  * @author King
  */
 private class QuickWayListener implements OnItemLongClickListener{
  @Override
  public boolean onItemLongClick(AdapterView arg0, View view,
    int pos, long id) {
   //pos不可用说明见下文
   return false;
  }
 }

如果这个方法是用在ListView长按事件中刚刚好,但在ExpandableListView中,第三个参数pos不能区分开点击的是父项还是子项,以及哪个父项或子项。

在ExpandableListView响应的onItemLongCkick方法中,pos参数值为:从上到下,父项+展现的子项到点击位置的数目(注意:是展现的,隐藏的子项不包括,从0开始)。
例如:
父项1(隐藏3个子项)
父项2
 |—子项2-0
 |—子项2-1
 |—子项2-2
长按子项2-1时,pos值为3。显然根据pos值是无法确定点击的是哪个子项或父项的。
因此依赖pos是很难处理点击位置的。

如果可以直接在onItemLongClick方法中获取groupPos,及childPos该多好呢?

于是看到了onItemLongClick方法第二个参数:view。这里的view是你按中的位置对应的view。view有个方法getTag(int key)。如果在创建此view的时候就把groupPos,childPos通过setTag(int key, Object value)设置进去,在响应onItemLongClick不就可以直接拿出来用了么。

现在就要讲到必须使用自定义的BaseExpandableListAdapter的理由了。

要把groupPos,childPos通过setTag的方式绑定到view中,就必须操作该view的创建过程。要控制这个过程就必须要在自定义BaseExpandableListAdapter中重写getGroupView及getChildView方法进行操作。如下:
代码如下:

public class AccountListAdapter extends BaseExpandableListAdapter {
 ...省略其他方法
 @Override
 public View getChildView(int groupPosition, int childPosition,
   boolean isLastChild, View convertView, ViewGroup parent) {
  //我这里仅通过自己写的mkChildView()方法创建TextView来显示文字,更复杂的可以通过LayoutInflater来填充一个view
  TextView childTv = mkChildView();
  // 标记位置
  // 必须使用资源Id当key(不是资源id会出现运行时异常),android本意应该是想用tag来保存资源id对应组件。
  // 将groupPosition,childPosition通过setTag保存,在onItemLongClick方法中就可以通过view参数直接拿到了!
                childTv.setTag(R.id.xxx01, groupPosition);
  childTv.setTag(R.id.xxx02, childPosition);
  return childTv;
 }
 @Override
 public View getGroupView(int groupPosition, boolean isExpanded,
   View convertView, ViewGroup parent) {
  TextView groupTv = mkGroupView();
  // 设置同getChildView一样
  groupTv.setTag(R.id.xxx01, groupPosition);
  groupTv.setTag(R.id.xxx02, -1); //设置-1表示长按时点击的是父项,到时好判断。
  groupTv.setText(groups[groupPosition]);
  return groupTv;
 }
}

完成了这一步,我们只需要在ExpandableListView响应的onItemLongClick方法时通过view.getTag(R.id.xxx01),view.getTag(R.id.xxx02)即可拿到groupPos,childPos.
如下:
代码如下:

       /**
  * 长按邮箱快捷选项
  * @author King
  */
 private class QuickWayListener implements OnItemLongClickListener{
  @Override
  public boolean onItemLongClick(AdapterView arg0, View view,
    int pos, long id) {
   int groupPos = (Integer)view.getTag(R.id.xxx01); //参数值是在setTag时使用的对应资源id号
   int childPos = (Integer)view.getTag(R.id.xxx02);
   if(childPos == -1){//长按的是父项
       //根据groupPos判断你长按的是哪个父项,做相应处理(弹框等)
   } else {
       //根据groupPos及childPos判断你长按的是哪个父项下的哪个子项,然后做相应处理。 
   }
   return false;
  }
 }

到这就写完了,貌似比较啰嗦。重写BaseExpandableListAdapter写的比较简洁,没看明白的朋友可以先到网上查下怎么自定义BaseExpandableListAdapter,和自定义BaseAdapter其实是一样的。

推荐阅读
  • 捕获并处理用户输入数字时的异常,提供详细的错误提示与指导
    在用户输入数字时,程序能够有效捕获并处理各种异常情况,如非法字符或格式错误,并提供详尽的错误提示和操作指导,确保用户能够准确输入有效的数字数据。通过这种方式,不仅提高了程序的健壮性和用户体验,还减少了因输入错误导致的系统故障。具体实现中,使用了Java的异常处理机制,结合Scanner类进行输入读取和验证,确保了输入的合法性和准确性。 ... [详细]
  • 本文探讨了Android系统中支持的图像格式及其在不同版本中的兼容性问题,重点涵盖了存储、HTTP传输、相机功能以及SparseArray的应用。文章详细分析了从Android 10 (API 29) 到Android 11 的存储规范变化,并讨论了这些变化对图像处理的影响。此外,还介绍了如何通过系统升级和代码优化来解决版本兼容性问题,以确保应用程序在不同Android版本中稳定运行。 ... [详细]
  • vtkGlyph3D 是一种强大的符号化可视化工具,能够将三维数据集中的每个点用预定义的几何图形(如球体或箭头)进行表示。该工具不仅支持自定义符号的方向和缩放比例,还能够在复杂的数据场中突出显示关键特征,从而提高数据的可解释性和可视化效果。通过这种方式,用户可以更直观地理解和分析三维数据集中的重要信息。 ... [详细]
  • MongoVUE基础操作指南:轻松上手数据库管理
    本文介绍了MongoVUE的基础操作,旨在帮助用户轻松掌握数据库管理技巧。MongoVUE是一款功能强大的MongoDB客户端工具,虽然需要注册,但其用户友好的界面和丰富的功能使其成为许多开发者的首选。文中详细解释了安装步骤、基本配置以及常见操作方法,并对一些常见的问题进行了修正和补充,确保用户能够快速上手并高效使用MongoVUE进行数据库管理。 ... [详细]
  • 深入解析 Android TextView 中 getImeActionLabel() 方法的使用与代码示例 ... [详细]
  • 在Python网络编程中,多线程技术的应用与优化是提升系统性能的关键。线程作为操作系统调度的基本单位,其主要功能是在进程内共享内存空间和资源,实现并行处理任务。当一个进程启动时,操作系统会为其分配内存空间,加载必要的资源和数据,并调度CPU进行执行。每个进程都拥有独立的地址空间,而线程则在此基础上进一步细化了任务的并行处理能力。通过合理设计和优化多线程程序,可以显著提高网络应用的响应速度和处理效率。 ... [详细]
  • HDU1176:免费馅饼问题的动态规划解法分析
    题目“免费馅饼”通过动态规划方法进行了解析。该问题的时间限制为 Java 2000ms 和其他语言 1000ms,内存限制为 Java 65536K 和其他语言 32768K。本文详细探讨了如何利用动态规划算法高效求解此问题,并对算法的时间复杂度和空间复杂度进行了深入分析。此外,还提供了具体的实现步骤和代码示例,帮助读者更好地理解和应用这一方法。 ... [详细]
  • 在处理遗留数据库的映射时,反向工程是一个重要的初始步骤。由于实体模式已经在数据库系统中存在,Hibernate 提供了自动化工具来简化这一过程,帮助开发人员快速生成持久化类和映射文件。通过反向工程,可以显著提高开发效率并减少手动配置的错误。此外,该工具还支持对现有数据库结构进行分析,自动生成符合 Hibernate 规范的配置文件,从而加速项目的启动和开发周期。 ... [详细]
  • PHP开发人员薪资水平分析:工程师平均工资概况
    PHP开发人员薪资水平分析:工程师平均工资概况 ... [详细]
  • 解决Android应用在手机安装时出现安全风险提示的方法与对策
    解决Android应用在手机安装时出现安全风险提示的方法与对策 ... [详细]
  • 在尝试为 Unity 编译一个简单的 Java 库时,运行 `ant jar` 命令后遇到了 Java I/O 异常。具体错误信息为“无法启动程序 ${aAPT},错误代码 2”,这通常表示指定的文件或目录不存在。此问题可能是由于环境配置不正确或路径设置有误导致的。建议检查相关路径和环境变量,确保所有依赖项都已正确安装和配置。 ... [详细]
  • 在遍历集合的过程中,若需根据特定条件对集合进行修改操作,如添加或删除元素,应特别注意避免引发 `ConcurrentModificationException` 异常。例如,在当前场景中,当集合中的对象ID与另一个集合中的对象ID不匹配时,需要向集合中添加新元素。为了避免这一异常,建议使用迭代器的 `remove` 方法或采用线程安全的集合类型,如 `CopyOnWriteArrayList`,以确保操作的安全性和一致性。 ... [详细]
  • 基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析
    基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析 ... [详细]
  • 如何在Mac上构建高效的本地服务器环境
    在Mac上构建高效的本地服务器环境,首先需要了解基本步骤:1. 配置目录基础;2. 启动Apache服务;3. 添加自定义文档至本地服务器;4. 查看自定义效果。此外,还可以通过手机或其他电脑访问本机服务器,以确保跨设备的兼容性和调试效果。Mac系统自带的Apache服务为本地开发提供了便捷的工具,本文将详细介绍每个步骤的具体操作方法。 ... [详细]
  • CAS 机制下的无锁队列设计与实现 ... [详细]
author-avatar
望尽天涯
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有