从SQLite取数据到自定义ListView时遇Resources$NotFoundException崩溃的解决
解决Android ListView加载数据时的Resources$NotFoundException崩溃问题
从你的崩溃日志里能马上定位到问题:android.content.res.Resources$NotFoundException: String resource ID #0x1。这个错误的根源很典型——你在给TextView设置int类型的数据时,误用了TextView的重载方法。
问题原因分析
TextView有两个常用的setText方法:
setText(String text):直接显示传入的字符串内容setText(int resId):根据传入的资源ID查找对应的字符串资源并显示
在你的FenceAdapter的getView方法里,这两行代码出了问题:
textViewSno.setText(fence.getSno()); // getSno()返回int类型 textViewRadi.setText(fence.getRadius()); // getRadius()返回int类型
你传入的是int类型的数字(比如1),系统会把这个数字当成字符串资源的ID去查找,但你的项目里并没有ID为0x1的字符串资源,所以直接抛出了资源找不到的异常,导致应用崩溃。
解决方案:把int类型转换为String
只需要把int类型的数值转换成String后再设置给TextView即可,有几种简单的实现方式:
- 使用
String.valueOf()方法(推荐,最清晰) - 拼接空字符串:
数值 + "" - 使用
Integer.toString()
修改后的getView方法中对应代码如下:
Fence fence = fenceList.get(position); TextView textViewSno = view.findViewById(R.id.textViewSnoLabel); TextView textViewLat = view.findViewById(R.id.textViewLatitudeValue); TextView textViewLon = view.findViewById(R.id.textViewLongitudeValue); TextView textViewRadi = view.findViewById(R.id.textViewRadiusValue); // 把int类型转为String后再设置 textViewSno.setText(String.valueOf(fence.getSno())); textViewLat.setText(String.valueOf(fence.getLat())); textViewLon.setText(String.valueOf(fence.getLon())); textViewRadi.setText(String.valueOf(fence.getRadius()));
额外优化:提升ListView性能
顺便给你提个小优化,你的当前getView方法每次都会重新inflate布局和查找控件,这样在列表条目较多时会影响性能。可以使用ViewHolder模式来缓存控件,复用convertView:
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; // 复用已有的View,避免重复inflate if (convertView == null) { LayoutInflater layoutInflater = LayoutInflater.from(context); convertView = layoutInflater.inflate(listLayoutRes, parent, false); holder = new ViewHolder(); // 只在第一次创建View时查找控件并缓存 holder.textViewSno = convertView.findViewById(R.id.textViewSnoLabel); holder.textViewLat = convertView.findViewById(R.id.textViewLatitudeValue); holder.textViewLon = convertView.findViewById(R.id.textViewLongitudeValue); holder.textViewRadi = convertView.findViewById(R.id.textViewRadiusValue); holder.buttonDel = convertView.findViewById(R.id.buttonDeleteFence); convertView.setTag(holder); } else { // 从Tag中取出缓存的ViewHolder holder = (ViewHolder) convertView.getTag(); } Fence fence = fenceList.get(position); // 设置数据(同样要转成String) holder.textViewSno.setText(String.valueOf(fence.getSno())); holder.textViewLat.setText(String.valueOf(fence.getLat())); holder.textViewLon.setText(String.valueOf(fence.getLon())); holder.textViewRadi.setText(String.valueOf(fence.getRadius())); // 这里可以给删除按钮添加点击事件 holder.buttonDel.setOnClickListener(v -> { // 示例:删除列表中的条目并更新UI fenceList.remove(position); notifyDataSetChanged(); // 记得同步删除数据库中的数据(需要你在DataBaseHelper中实现delete方法) // dataBaseHelper.deleteFence(fence.getSno()); }); return convertView; } // 内部ViewHolder类,用于缓存控件 private static class ViewHolder { TextView textViewSno; TextView textViewLat; TextView textViewLon; TextView textViewRadi; Button buttonDel; }
这样修改后,不仅能解决崩溃问题,还能提升ListView的滚动流畅度。
内容的提问来源于stack exchange,提问作者Idesh
相关产品推荐
相关产品推荐

