You need to enable JavaScript to run this app. Android Studio中从RecyclerView向SQLite插入数据及收藏按钮SharedPreferences配置问题
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中从RecyclerView向SQLite插入数据及收藏按钮SharedPreferences配置问题

问题解决方案

1. 解决「no such table: favorites」报错

这个报错是因为旧版本的数据库文件已经存在于你的手机/模拟器中,SQLiteOpenHelper的onCreate方法只会在数据库第一次创建的时候执行,你后续修改了建表逻辑但没有升级数据库版本,导致favorites表没有被创建:

  • 临时测试解决:直接卸载当前APP重新安装,旧的数据库文件会被清除,第一次启动会触发onCreate建表
  • 正式修复:将FavDB构造方法中的数据库版本号从1改为2,触发onUpgrade方法删除旧表重建:
public FavDB(Context context) {
    super(context, DB_NAME, null, 2); // 版本号从1改到2
}

2. 解决db.insert返回-1的问题

表创建成功后这个问题会自动消失,如果还有返回-1的情况,检查以下两点:

  • 确认插入的FavVenueItem所有字段都不为空,你当前初始化的数据都是全的,不会有这个问题
  • 可选优化:表中image字段当前定义为TEXT类型,但你插入的是int类型的资源ID,建议将建表语句中的image字段改为INTEGER类型,避免后续类型不匹配问题:
db.execSQL(" CREATE TABLE " +TABLE_NAME + "(" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + Venue_name + " TEXT, " +Venue_type+ " TEXT, " +Venue_budget+ " TEXT, "+Venue_image+ " INTEGER, "+Venue_contact+ " TEXT, "+FAV_STATUS+ " TEXT)");

3. 优化收藏逻辑&添加状态持久化

3.1 修复按钮状态错乱问题

你当前在onBindViewHolder中没有设置收藏按钮的初始状态,RecyclerView滑动复用条目时会出现状态错乱,修改onBindViewHolder代码:

@Override
public void onBindViewHolder(@NonNull @NotNull ViewHolder holder, int position) {
    final FavVenueItem venueItem = VenueItemsList.get(position);
    holder.ImageView.setImageResource(venueItem.getImageResourse());
    holder.Name.setText(venueItem.getVenuename());
    holder.venuetype.setText(venueItem.getType());
    holder.venuebudget.setText(venueItem.getBudget());
    holder.venuecontact.setText(venueItem.getContact());
    // 新增:根据收藏状态设置按钮图标
    if(venueItem.getFavStatus().equals("1")){
        holder.favbtn.setBackgroundResource(R.drawable.ic_baseline_favorite_24);
    }else{
        holder.favbtn.setBackgroundResource(R.drawable.ic_baseline_favorite_border_24);
    }
}

3.2 补全取消收藏逻辑

你当前代码中取消收藏时没有删除数据库中的对应记录,收藏Fragment中会一直显示已经取消的条目,修改ViewHolder中点击事件的else分支:

} else {
    venueItem.setFavStatus("0");
    // 新增:删除数据库中对应的收藏记录
    SQLiteDatabase db = favDB.getWritableDatabase();
    db.delete(FavDB.TABLE_NAME, FavDB.Venue_name + "=?", new String[]{venueItem.getVenuename()});
    favbtn.setBackgroundResource(R.drawable.ic_baseline_favorite_border_24);
}

3.3 添加SharedPreferences状态存储(可选)

如果需要用SharedPreferences存储收藏状态(更推荐直接从数据库读状态,SP适合少量配置存储),实现如下:
首先在Adapter中初始化SharedPreferences:

private SharedPreferences sp;
public VenueAdapter(ArrayList<FavVenueItem> VenueItems, Context context) {
    this.VenueItemsList = VenueItems;
    this.context = context;
    sp = context.getSharedPreferences("fav_sp", Context.MODE_PRIVATE);
}

点击收藏时存储状态:

if (venueItem.getFavStatus().equals("0")) {
    venueItem.setFavStatus("1");
    favDB.inserttVenueData(venueItem);
    // 存储SP状态,用场馆名作为key
    sp.edit().putString(venueItem.getVenuename(), "1").apply();
    favbtn.setBackgroundResource(R.drawable.ic_baseline_favorite_24);
} else {
    venueItem.setFavStatus("0");
    SQLiteDatabase db = favDB.getWritableDatabase();
    db.delete(FavDB.TABLE_NAME, FavDB.Venue_name + "=?", new String[]{venueItem.getVenuename()});
    // 删除SP中对应的状态
    sp.edit().remove(venueItem.getVenuename()).apply();
    favbtn.setBackgroundResource(R.drawable.ic_baseline_favorite_border_24);
}

加载列表时从SP读取初始状态:

// 在setData方法之后或者onBindViewHolder中读取
String favStatus = sp.getString(venueItem.getVenuename(), "0");
venueItem.setFavStatus(favStatus);

内容的提问来源于stack exchange,提问作者Neha M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 18:15:06