java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder问题解决

本文详细解析了在使用RecyclerView更新Item数据时遇到的问题及其解决方法。重点介绍了如何判断要更新的Item是否在屏幕可视区域内,以及当列表含有Header时如何正确通知数据变更。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我是在使用RecyclerView更新了某个item的数据,调用notifyItemChanged()的时候出现的这个问题。具体也没有报是哪一行的问题,根据错误提示,意思是操作的这个viewholder当前不是被绑定的,因为RecyclerView有缓存机制,未在屏幕上显示的item会被暂时回收,即detached。

1、出现这个问题的原因是更新了不在屏幕中显示的item,解决办法是判断要更新的item是不是在屏幕中,判断方法是获取RecyclerView的LayoutManager,前提是RecyclerView设置的LayoutManager是LinearLayoutManager。获取第一个可见位置和最后一个可见位置的position,判断当前要更新的item的position在这个范围内才更新。

LinearLayoutManager linearManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//最后一个可见view的位置
int mLastVisibleItemPosition = linearManager.findLastVisibleItemPosition();
//第一个可见view的位置
int mFirstVisibleItemPosition = linearManager.findFirstVisibleItemPosition();

2、但是我的列表只有一条数据,并且是在屏幕中显示的,我在notifyItemChanged(0)还是报了这个错,经过仔细研究代码,我发现我的RecyclerView添加了Header,这样position=0的位置其实是header,所以出现了这样的问题。所以更新List中position位置的数据后要更新的Adapter的位置是position+1,改成notifyItemChanged(1)之后问题解决。

 

### 错误原因分析 `java.lang.IllegalArgumentException: java.lang.Enum is not an enum class` 错误通常出现在使用枚举类型时,传入了错误的类型或试图将非枚举类当作枚举处理。Java 的 `Enum` 类是所有枚举类型的父类,但它本身并不是一个枚举类,因此不能直接使用 `Enum.valueOf()` 或其他枚举操作来处理它。 此错误可能由以下几种情况引发: - 在使用 `Enum.valueOf(Class<T> enumClass, String name)` 方法时,传入了一个非枚举类的 `Class` 对象。 - 在某些框架(如 MyBatis)中,如果映射配置错误,可能会导致框架尝试将一个非枚举类型解析为枚举值。 - 枚举类本身未正确声明,或者在反射调用时错误地传递了 `Enum.class` 而不是具体的枚举子类。 ### 修复方法 1. **确保传入的类是具体的枚举类** 在调用 `Enum.valueOf()` 时,确保传入的是实际的枚举类,而不是 `Enum.class`。例如: ```java public enum Color { RED, GREEN, BLUE; } // 正确使用 Enum.valueOf(Color.class, "RED"); ``` 如果传入 `Enum.class`,则会抛出 `IllegalArgumentException`。 2. **检查 MyBatis 映射配置** 如果在使用 MyBatis 时出现此错误,可能是由于映射文件中配置了错误的枚举类型。例如,`jdbcType` 或 `resultType` 错误地引用了 `Enum` 而不是具体的枚举类。需要确保在 MyBatis 映射 XML 中正确配置枚举类型: ```xml <resultMap id="demoResultMap" type="com.example.Demo"> <result property="color" column="color" typeHandler="com.example.EnumTypeHandler" javaType="com.example.Color"/> </resultMap> ``` 3. **避免反射中误用 `Enum.class`** 在使用反射处理枚举时,应确保获取的是具体的枚举类,而不是 `Enum.class`。例如,在获取枚举值时,应使用具体的枚举类的 `class` 对象: ```java Class<?> clazz = Class.forName("com.example.Color"); if (clazz.isEnum()) { Object enumValue = Enum.valueOf((Class<Enum>) clazz, "RED"); } ``` 4. **检查框架版本兼容性** 如果使用的是较旧版本的 Spring 或 MyBatis,可能存在对枚举处理的兼容性问题。建议升级到最新稳定版本,以确保更好地支持枚举类型。 ### 示例代码 以下是一个简单的枚举使用示例,展示了如何正确地将字符串转换为枚举常量: ```java public class EnumExample { public enum Status { ACTIVE, INACTIVE, PENDING; } public static void main(String[] args) { String input = "ACTIVE"; try { Status status = Enum.valueOf(Status.class, input); System.out.println("Parsed status: " + status); } catch (IllegalArgumentException e) { System.out.println("Invalid enum value: " + input); } } } ``` 上述代码中,如果输入的字符串不是 `Status` 枚举中的常量,则会捕获 `IllegalArgumentException` 并输出提示信息。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值