From a9f3c9fa815729b84b8233142bae216a44db58cb Mon Sep 17 00:00:00 2001 From: MiMo Date: Mon, 20 Jul 2026 19:15:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(gallery):=20=E5=AE=9E=E7=8E=B0=E7=BD=AE?= =?UTF-8?q?=E9=A1=B6=E7=9B=B8=E5=86=8C=E6=8E=92=E5=BA=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 数据库升级 - PinnedAlbumDbHelper 版本升级至 2 - 新增 sort_order 字段存储排序号 - 自动迁移旧数据并分配排序号 2. 置顶排序逻辑 - 新置顶相册排序号设为1,其他相册排序号+1 - 取消置顶时,后续相册排序号自动-1 - 使用事务确保数据一致性 3. 列表加载与刷新 - 加载相册时按排序号由小到大排列 - 刷新列表时保持排序号顺序显示 - 使用 LinkedHashMap 保持插入顺序 4. 调试日志 - 置顶操作后输出所有相册排序号 - 取消置顶时输出原排序号 修改文件: - PinnedAlbumDbHelper.java - MainActivity.java - AlbumAdapter.java - build.properties --- gallery/build.properties | 4 +- .../winboll/studio/gallery/AlbumAdapter.java | 21 +++- .../winboll/studio/gallery/MainActivity.java | 24 +++- .../studio/gallery/PinnedAlbumDbHelper.java | 105 ++++++++++++++++-- 4 files changed, 130 insertions(+), 24 deletions(-) diff --git a/gallery/build.properties b/gallery/build.properties index f57021c..4b70e58 100644 --- a/gallery/build.properties +++ b/gallery/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Sun Jul 19 15:10:49 HKT 2026 +#Mon Jul 20 19:13:11 CST 2026 stageCount=18 libraryProject= baseVersion=15.0 publishVersion=15.0.17 -buildCount=0 +buildCount=15 baseBetaVersion=15.0.18 diff --git a/gallery/src/main/java/cc/winboll/studio/gallery/AlbumAdapter.java b/gallery/src/main/java/cc/winboll/studio/gallery/AlbumAdapter.java index 1e31eb0..57a1f2d 100644 --- a/gallery/src/main/java/cc/winboll/studio/gallery/AlbumAdapter.java +++ b/gallery/src/main/java/cc/winboll/studio/gallery/AlbumAdapter.java @@ -86,17 +86,28 @@ public class AlbumAdapter extends RecyclerView.Adapter public void refreshPinned() { if (pinnedDbHelper != null && albums != null && !albums.isEmpty()) { - Set pinnedPaths = new HashSet(); - pinnedPaths.addAll(Arrays.asList(pinnedDbHelper.getPinnedPaths())); + java.util.LinkedHashMap pinnedPathMap = pinnedDbHelper.getPinnedPathsWithSortOrder(); + Set pinnedPaths = pinnedPathMap.keySet(); ArrayList pinned = new ArrayList(); ArrayList unpinned = new ArrayList(); + + // 按照排序号顺序添加置顶相册 + for (String pinnedPath : pinnedPathMap.keySet()) { + for (Album album : albums) { + if (album.getPath().equals(pinnedPath)) { + pinned.add(album); + break; + } + } + } + + // 添加非置顶相册 for (Album album : albums) { - if (pinnedPaths.contains(album.getPath())) { - pinned.add(album); - } else { + if (!pinnedPaths.contains(album.getPath())) { unpinned.add(album); } } + albums.clear(); albums.addAll(pinned); albums.addAll(unpinned); diff --git a/gallery/src/main/java/cc/winboll/studio/gallery/MainActivity.java b/gallery/src/main/java/cc/winboll/studio/gallery/MainActivity.java index e5063c9..0dab552 100644 --- a/gallery/src/main/java/cc/winboll/studio/gallery/MainActivity.java +++ b/gallery/src/main/java/cc/winboll/studio/gallery/MainActivity.java @@ -216,9 +216,9 @@ public class MainActivity extends AppCompatActivity { AlbumCoverDbHelper coverDbHelper = AlbumCoverDbHelper.getInstance(this); PinnedAlbumDbHelper pinnedDbHelper = PinnedAlbumDbHelper.getInstance(this); - Set pinnedPaths = new HashSet(); - String[] pinnedArray = pinnedDbHelper.getPinnedPaths(); - pinnedPaths.addAll(Arrays.asList(pinnedArray)); + // 获取带排序号的置顶路径映射(已按排序号排序) + java.util.LinkedHashMap pinnedPathMap = pinnedDbHelper.getPinnedPathsWithSortOrder(); + Set pinnedPaths = pinnedPathMap.keySet(); ArrayList albums = new ArrayList(); @@ -252,15 +252,27 @@ public class MainActivity extends AppCompatActivity { } } + // 按照排序号顺序添加置顶相册 ArrayList pinned = new ArrayList(); ArrayList unpinned = new ArrayList(); + + // 先按照pinnedPathMap的顺序(排序号顺序)添加置顶相册 + for (String pinnedPath : pinnedPathMap.keySet()) { + for (Album album : albums) { + if (album.getPath().equals(pinnedPath)) { + pinned.add(album); + break; + } + } + } + + // 添加非置顶相册 for (Album album : albums) { - if (pinnedPaths.contains(album.getPath())) { - pinned.add(album); - } else { + if (!pinnedPaths.contains(album.getPath())) { unpinned.add(album); } } + pinned.addAll(unpinned); return pinned; } diff --git a/gallery/src/main/java/cc/winboll/studio/gallery/PinnedAlbumDbHelper.java b/gallery/src/main/java/cc/winboll/studio/gallery/PinnedAlbumDbHelper.java index 6dc35e9..23b9038 100644 --- a/gallery/src/main/java/cc/winboll/studio/gallery/PinnedAlbumDbHelper.java +++ b/gallery/src/main/java/cc/winboll/studio/gallery/PinnedAlbumDbHelper.java @@ -6,16 +6,19 @@ 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 = 1; + 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_PATH + " TEXT PRIMARY KEY, " + + COLUMN_SORT_ORDER + " INTEGER DEFAULT 0)"; private static PinnedAlbumDbHelper dbHelper; @@ -37,22 +40,87 @@ public class PinnedAlbumDbHelper extends SQLiteOpenHelper { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); - onCreate(db); + 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(); - ContentValues values = new ContentValues(); - values.put(COLUMN_PATH, albumPath); - db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_IGNORE); - LogUtils.d(TAG, "pinAlbum: " + albumPath); + 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.delete(TABLE_NAME, COLUMN_PATH + " = ?", new String[]{albumPath}); - LogUtils.d(TAG, "unpinAlbum: " + albumPath); + 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) { @@ -66,7 +134,8 @@ public class PinnedAlbumDbHelper extends SQLiteOpenHelper { public String[] getPinnedPaths() { SQLiteDatabase db = getReadableDatabase(); - Cursor cursor = db.query(TABLE_NAME, new String[]{COLUMN_PATH}, null, null, null, null, null); + 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()) { @@ -75,4 +144,18 @@ public class PinnedAlbumDbHelper extends SQLiteOpenHelper { cursor.close(); return paths; } + + public LinkedHashMap 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 map = new LinkedHashMap(); + while (cursor.moveToNext()) { + String path = cursor.getString(0); + int sortOrder = cursor.getInt(1); + map.put(path, sortOrder); + } + cursor.close(); + return map; + } } \ No newline at end of file