如何在Android Studio中结合SQLite与Picasso实现GridView图片加载
我来帮你搞定用Picasso加载SQLite里的图片URL到GridView的问题,一步步来,很清晰的:
完整解决方案步骤
1. 先定义历史记录实体类
创建一个History类来封装每条记录的用户名和图片URL,方便后续数据传递和处理:
public class History { private String username; private String imageUrl; public History(String username, String imageUrl) { this.username = username; this.imageUrl = imageUrl; } // Getter方法,供Adapter获取数据 public String getUsername() { return username; } public String getImageUrl() { return imageUrl; } }
2. 完善SQLite数据库操作
确保你的Database类能正确插入、查询并返回List<History>类型的历史数据,避免直接返回原始Cursor:
public class Database extends SQLiteOpenHelper { // 常量定义,方便维护 private static final String DB_NAME = "SearchHistory.db"; private static final int DB_VERSION = 1; private static final String TABLE_HISTORY = "history"; private static final String COLUMN_USERNAME = "username"; private static final String COLUMN_IMAGE_URL = "image_url"; public Database(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建历史记录表,用username作为主键避免重复 String createTable = "CREATE TABLE " + TABLE_HISTORY + " (" + COLUMN_USERNAME + " TEXT PRIMARY KEY," + COLUMN_IMAGE_URL + " TEXT)"; db.execSQL(createTable); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_HISTORY); onCreate(db); } // 插入/更新历史记录(replace会自动覆盖重复的username) public void insertOrUpdateHistory(String username, String imageUrl) { SQLiteDatabase db = getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_USERNAME, username); values.put(COLUMN_IMAGE_URL, imageUrl); db.replace(TABLE_HISTORY, null, values); db.close(); } // 查询所有历史记录,返回封装好的List<History> public List<History> History_list() { List<History> historyList = new ArrayList<>(); SQLiteDatabase db = getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_HISTORY, null); if (cursor.moveToFirst()) { do { String username = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_USERNAME)); String imageUrl = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_IMAGE_URL)); historyList.add(new History(username, imageUrl)); } while (cursor.moveToNext()); } cursor.close(); db.close(); return historyList; } }
3. 为GridView创建自定义Adapter(核心步骤)
这一步是实现Picasso加载图片的关键,在Adapter的getView方法中调用Picasso加载图片URL:
public class HistoryAdapter extends BaseAdapter { private Context context; private List<History> historyList; public HistoryAdapter(Context context, List<History> historyList) { this.context = context; this.historyList = historyList; } @Override public int getCount() { return historyList.size(); } @Override public Object getItem(int position) { return historyList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; // 复用View优化性能 if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.history_item, parent, false); holder = new ViewHolder(); holder.avatarIv = convertView.findViewById(R.id.iv_avatar); holder.usernameTv = convertView.findViewById(R.id.tv_username); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } History currentHistory = historyList.get(position); // 设置用户名 holder.usernameTv.setText(currentHistory.getUsername()); // 用Picasso加载图片到ImageView Picasso.get() .load(currentHistory.getImageUrl()) .placeholder(R.drawable.default_avatar) // 加载中的占位图 .error(R.drawable.error_avatar) // 加载失败的占位图 .centerCrop() .into(holder.avatarIv); return convertView; } // ViewHolder类,避免重复findViewById private static class ViewHolder { ImageView avatarIv; TextView usernameTv; } }
对应的history_item.xml布局示例(你可以根据需求调整样式):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:padding="10dp"> <ImageView android:id="@+id/iv_avatar" android:layout_width="70dp" android:layout_height="70dp" android:scaleType="centerCrop" android:background="@drawable/avatar_round" /> <TextView android:id="@+id/tv_username" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:textSize="13sp" android:textColor="@color/black" /> </LinearLayout>
4. 在MainActivity中绑定数据到GridView
在onResume方法中获取历史数据,初始化Adapter并设置给GridView:
public class MainActivity extends AppCompatActivity { private GridView historyGridView; private HistoryAdapter historyAdapter; private List<History> historyList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化GridView historyGridView = findViewById(R.id.grid_view_history); } @Override protected void onResume() { super.onResume(); Database db = new Database(getApplicationContext()); historyList = db.History_list(); if (historyList.isEmpty()) { // 没有历史记录时的处理,比如显示空状态提示 ImageButton timerBtn = findViewById(R.id.users_history_timer); // 这里可以添加隐藏GridView、显示空布局的逻辑 } else { // 初始化Adapter并绑定到GridView historyAdapter = new HistoryAdapter(this, historyList); historyGridView.setAdapter(historyAdapter); } } // 用户搜索完成后调用此方法保存历史记录 private void saveSearchHistory(String username, String imageUrl) { Database db = new Database(getApplicationContext()); db.insertOrUpdateHistory(username, imageUrl); // 保存后刷新列表 historyList = db.History_list(); if (historyAdapter != null) { historyAdapter.notifyDataSetChanged(); } } }
5. 检查必要配置
- 添加Picasso依赖:在
app/build.gradle(Module级别)的dependencies中加入:implementation 'com.squareup.picasso:picasso:2.71828' - 网络权限:如果图片URL是网络地址,需要在
AndroidManifest.xml中添加:<uses-permission android:name="android.permission.INTERNET" />
内容的提问来源于stack exchange,提问作者user8143839
相关产品推荐
相关产品推荐

