feat(gallery): 实现置顶相册排序功能

1. 数据库升级
   - PinnedAlbumDbHelper 版本升级至 2
   - 新增 sort_order 字段存储排序号
   - 自动迁移旧数据并分配排序号

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

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

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

修改文件:
- PinnedAlbumDbHelper.java
- MainActivity.java
- AlbumAdapter.java
- build.properties
This commit is contained in:
MiMo
2026-07-20 19:15:59 +08:00
parent ce01ecf138
commit a9f3c9fa81
4 changed files with 130 additions and 24 deletions
+2 -2
View File
@@ -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
@@ -86,17 +86,28 @@ public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder>
public void refreshPinned() {
if (pinnedDbHelper != null && albums != null && !albums.isEmpty()) {
Set<String> pinnedPaths = new HashSet<String>();
pinnedPaths.addAll(Arrays.asList(pinnedDbHelper.getPinnedPaths()));
java.util.LinkedHashMap<String, Integer> pinnedPathMap = pinnedDbHelper.getPinnedPathsWithSortOrder();
Set<String> pinnedPaths = pinnedPathMap.keySet();
ArrayList<Album> pinned = new ArrayList<Album>();
ArrayList<Album> unpinned = new ArrayList<Album>();
// 按照排序号顺序添加置顶相册
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);
@@ -216,9 +216,9 @@ public class MainActivity extends AppCompatActivity {
AlbumCoverDbHelper coverDbHelper = AlbumCoverDbHelper.getInstance(this);
PinnedAlbumDbHelper pinnedDbHelper = PinnedAlbumDbHelper.getInstance(this);
Set<String> pinnedPaths = new HashSet<String>();
String[] pinnedArray = pinnedDbHelper.getPinnedPaths();
pinnedPaths.addAll(Arrays.asList(pinnedArray));
// 获取带排序号的置顶路径映射(已按排序号排序)
java.util.LinkedHashMap<String, Integer> pinnedPathMap = pinnedDbHelper.getPinnedPathsWithSortOrder();
Set<String> pinnedPaths = pinnedPathMap.keySet();
ArrayList<Album> albums = new ArrayList<Album>();
@@ -252,15 +252,27 @@ public class MainActivity extends AppCompatActivity {
}
}
// 按照排序号顺序添加置顶相册
ArrayList<Album> pinned = new ArrayList<Album>();
ArrayList<Album> unpinned = new ArrayList<Album>();
// 先按照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;
}
@@ -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<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;
}
}