如何用SQLite从数组读取数据并通过RecyclerView展示列表?
完整实现指南:SQLite + RecyclerView 展示带图片的列表
看起来你已经迈出了第一步,接下来咱们把整个流程补全,从SQLite取数到RecyclerView展示一步到位:
1. 补全RecyclerView Adapter的完整实现
你的NotificationAdapter已经有了雏形,咱们把核心方法补全,同时改成支持外部传入数据的结构(方便后续从SQLite获取数据后注入):
public class NotificationAdapter extends RecyclerView.Adapter<NotificationAdapter.NotificationDetailsHolder> { private List<NotificationHolder> notificationHolderList; private Context context; // 改成接收外部数据的构造函数,替代原来硬编码的测试数据 public NotificationAdapter(Context context, List<NotificationHolder> notificationHolderList) { this.context = context; this.notificationHolderList = notificationHolderList; } @Override public NotificationDetailsHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 加载列表项的布局文件 View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_notification, parent, false); return new NotificationDetailsHolder(itemView); } @Override public void onBindViewHolder(NotificationDetailsHolder holder, int position) { // 把数据绑定到列表项的控件上 NotificationHolder currentItem = notificationHolderList.get(position); holder.tvName.setText(currentItem.getName()); holder.tvDetails.setText(currentItem.getDetails()); // 如果是资源ID直接设置,要是存的是图片路径,后面会说怎么处理 holder.ivIcon.setImageResource(currentItem.getImageResId()); } @Override public int getItemCount() { // 返回列表总条数,避免空指针 return notificationHolderList != null ? notificationHolderList.size() : 0; } // 内部ViewHolder类,对应列表项的控件 public static class NotificationDetailsHolder extends RecyclerView.ViewHolder { TextView tvName; TextView tvDetails; ImageView ivIcon; public NotificationDetailsHolder(View itemView) { super(itemView); tvName = itemView.findViewById(R.id.tv_name); tvDetails = itemView.findViewById(R.id.tv_details); ivIcon = itemView.findViewById(R.id.iv_icon); } } } // 你的数据模型类,要把getter方法补全 public class NotificationHolder { private String name; private String details; private int imageResId; public NotificationHolder(String name, String details, int imageResId) { this.name = name; this.details = details; this.imageResId = imageResId; } // 必须的getter方法,供Adapter读取数据 public String getName() { return name; } public String getDetails() { return details; } public int getImageResId() { return imageResId; } }
⚠️ 注意:你需要先创建一个列表项布局item_notification.xml,里面包含两个TextView和一个ImageView,ID要和ViewHolder里的findViewById对应上。
2. 实现SQLite数据读取逻辑
接下来写SQLite的数据库帮助类,负责创建表和查询数据:
public class NotificationDbHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "notifications.db"; private static final int DATABASE_VERSION = 1; // 表和列的定义 private static final String TABLE_NOTIFICATIONS = "notifications"; private static final String COLUMN_ID = "_id"; private static final String COLUMN_NAME = "name"; private static final String COLUMN_DETAILS = "details"; private static final String COLUMN_IMAGE_RES_ID = "image_res_id"; public NotificationDbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建表的SQL语句 String CREATE_TABLE = "CREATE TABLE " + TABLE_NOTIFICATIONS + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_NAME + " TEXT NOT NULL," + COLUMN_DETAILS + " TEXT NOT NULL," + COLUMN_IMAGE_RES_ID + " INTEGER NOT NULL" + ")"; db.execSQL(CREATE_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 升级时删除旧表重建(实际项目可以做更优雅的迁移) db.execSQL("DROP TABLE IF EXISTS " + TABLE_NOTIFICATIONS); onCreate(db); } // 查询所有数据的方法,返回我们需要的List public List<NotificationHolder> getAllNotifications() { List<NotificationHolder> notificationList = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); // 查询表中所有记录 Cursor cursor = db.query(TABLE_NOTIFICATIONS, null, null, null, null, null, null); if (cursor.moveToFirst()) { do { // 从游标中取出数据,封装成NotificationHolder对象 String name = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME)); String details = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_DETAILS)); int imageResId = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_IMAGE_RES_ID)); notificationList.add(new NotificationHolder(name, details, imageResId)); } while (cursor.moveToNext()); } cursor.close(); db.close(); return notificationList; } }
如果你的图片不是存资源ID,而是本地路径或者二进制Blob,需要调整:
- 本地路径:把
COLUMN_IMAGE_RES_ID改成COLUMN_IMAGE_PATH(类型TEXT),读取后用BitmapFactory.decodeFile()加载,或者用Glide/Picasso更省心。 - 二进制Blob:列类型改成BLOB,读取时用
cursor.getBlob()转成Bitmap。
3. 在Activity/Fragment中绑定所有组件
最后一步,在你的页面里把RecyclerView、数据库、Adapter串起来:
public class NotificationActivity extends AppCompatActivity { private RecyclerView recyclerView; private NotificationAdapter adapter; private NotificationDbHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_notification); // 初始化RecyclerView,设置线性布局管理器 recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); // 从数据库获取数据 dbHelper = new NotificationDbHelper(this); List<NotificationHolder> notificationList = dbHelper.getAllNotifications(); // 设置Adapter adapter = new NotificationAdapter(this, notificationList); recyclerView.setAdapter(adapter); } @Override protected void onDestroy() { super.onDestroy(); // 记得关闭数据库连接 dbHelper.close(); } }
额外优化建议
- 图片加载:如果图片数量多或者尺寸大,建议用Glide框架加载,避免内存溢出,比如
Glide.with(context).load(currentItem.getImageResId()).into(holder.ivIcon); - 数据更新:如果后续需要刷新列表,可以给Adapter加一个
updateData(List<NotificationHolder> newData)方法,更新内部列表后调用notifyDataSetChanged()。
内容的提问来源于stack exchange,提问作者user7620502
相关产品推荐
相关产品推荐

