Files
PowerBell/gallery/src/main/java/cc/winboll/studio/gallery/PinnedAlbumDbHelper.java
T
MiMo a9f3c9fa81 feat(gallery): 实现置顶相册排序功能
1. 数据库升级
   - PinnedAlbumDbHelper 版本升级至 2
   - 新增 sort_order 字段存储排序号
   - 自动迁移旧数据并分配排序号

2. 置顶排序逻辑
   - 新置顶相册排序号设为1,其他相册排序号+1
   - 取消置顶时,后续相册排序号自动-1
   - 使用事务确保数据一致性

3. 列表加载与刷新
   - 加载相册时按排序号由小到大排列
   - 刷新列表时保持排序号顺序显示
   - 使用 LinkedHashMap 保持插入顺序

4. 调试日志
   - 置顶操作后输出所有相册排序号
   - 取消置顶时输出原排序号

修改文件:
- PinnedAlbumDbHelper.java
- MainActivity.java
- AlbumAdapter.java
- build.properties
2026-07-20 19:15:59 +08:00

161 lines
6.5 KiB
Java

package cc.winboll.studio.gallery;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import cc.winboll.studio.libappbase.LogUtils;
import java.util.LinkedHashMap;
public class PinnedAlbumDbHelper extends SQLiteOpenHelper {
public static final String TAG = "PinnedAlbumDbHelper";
private static final String DB_NAME = "pinned_album.db";
private static final int DB_VERSION = 2;
private static final String TABLE_NAME = "pinned_albums";
private static final String COLUMN_PATH = "album_path";
private static final String COLUMN_SORT_ORDER = "sort_order";
private static final String SQL_CREATE = "CREATE TABLE " + TABLE_NAME + " ("
+ COLUMN_PATH + " TEXT PRIMARY KEY, "
+ COLUMN_SORT_ORDER + " INTEGER DEFAULT 0)";
private static PinnedAlbumDbHelper dbHelper;
public static PinnedAlbumDbHelper getInstance(Context context) {
if (dbHelper == null) {
dbHelper = new PinnedAlbumDbHelper(context.getApplicationContext());
}
return dbHelper;
}
public PinnedAlbumDbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
// 创建新表
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME + "_new");
db.execSQL("CREATE TABLE " + TABLE_NAME + "_new ("
+ COLUMN_PATH + " TEXT PRIMARY KEY, "
+ COLUMN_SORT_ORDER + " INTEGER DEFAULT 0)");
// 迁移旧数据,为现有记录分配排序号(按原始顺序)
Cursor cursor = db.query(TABLE_NAME, new String[]{COLUMN_PATH}, null, null, null, null, null);
int sortOrder = 1;
while (cursor.moveToNext()) {
String path = cursor.getString(0);
ContentValues values = new ContentValues();
values.put(COLUMN_PATH, path);
values.put(COLUMN_SORT_ORDER, sortOrder++);
db.insert(TABLE_NAME + "_new", null, values);
}
cursor.close();
// 删除旧表,重命名新表
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
db.execSQL("ALTER TABLE " + TABLE_NAME + "_new RENAME TO " + TABLE_NAME);
}
}
public void pinAlbum(String albumPath) {
SQLiteDatabase db = getWritableDatabase();
db.beginTransaction();
try {
// 将所有现有置顶数据的排序号加1
db.execSQL("UPDATE " + TABLE_NAME + " SET " + COLUMN_SORT_ORDER + " = " + COLUMN_SORT_ORDER + " + 1");
// 插入新数据,排序号为1
ContentValues insertValues = new ContentValues();
insertValues.put(COLUMN_PATH, albumPath);
insertValues.put(COLUMN_SORT_ORDER, 1);
db.insertWithOnConflict(TABLE_NAME, null, insertValues, SQLiteDatabase.CONFLICT_REPLACE);
db.setTransactionSuccessful();
// 查询所有置顶相册的排序号并输出调试信息
Cursor cursor = db.query(TABLE_NAME, new String[]{COLUMN_PATH, COLUMN_SORT_ORDER},
null, null, null, null, COLUMN_SORT_ORDER + " ASC");
StringBuilder sb = new StringBuilder("All pinned albums after pin:\n");
while (cursor.moveToNext()) {
String path = cursor.getString(0);
int sortOrder = cursor.getInt(1);
sb.append(" [").append(sortOrder).append("] ").append(path).append("\n");
}
cursor.close();
LogUtils.d(TAG, sb.toString());
} finally {
db.endTransaction();
}
}
public void unpinAlbum(String albumPath) {
SQLiteDatabase db = getWritableDatabase();
db.beginTransaction();
try {
// 获取要取消置顶的相册的排序号
Cursor cursor = db.query(TABLE_NAME, new String[]{COLUMN_SORT_ORDER},
COLUMN_PATH + " = ?", new String[]{albumPath}, null, null, null);
if (cursor.moveToFirst()) {
int sortNumber = cursor.getInt(0);
cursor.close();
// 将排序号大于该排序号的记录减1
db.execSQL("UPDATE " + TABLE_NAME + " SET " + COLUMN_SORT_ORDER + " = " + COLUMN_SORT_ORDER + " - 1 WHERE " + COLUMN_SORT_ORDER + " > ?", new Object[]{sortNumber});
// 删除该相册的置顶记录
db.delete(TABLE_NAME, COLUMN_PATH + " = ?", new String[]{albumPath});
LogUtils.d(TAG, "unpinAlbum: " + albumPath + ", sort number was: " + sortNumber);
} else {
cursor.close();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
public boolean isPinned(String albumPath) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, null, COLUMN_PATH + " = ?",
new String[]{albumPath}, null, null, null);
boolean pinned = cursor.getCount() > 0;
cursor.close();
return pinned;
}
public String[] getPinnedPaths() {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, new String[]{COLUMN_PATH}, null, null, null, null,
COLUMN_SORT_ORDER + " ASC");
String[] paths = new String[cursor.getCount()];
int i = 0;
while (cursor.moveToNext()) {
paths[i++] = cursor.getString(0);
}
cursor.close();
return paths;
}
public LinkedHashMap<String, Integer> getPinnedPathsWithSortOrder() {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, new String[]{COLUMN_PATH, COLUMN_SORT_ORDER},
null, null, null, null, COLUMN_SORT_ORDER + " ASC");
LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>();
while (cursor.moveToNext()) {
String path = cursor.getString(0);
int sortOrder = cursor.getInt(1);
map.put(path, sortOrder);
}
cursor.close();
return map;
}
}