添加相册集浏览窗口排序功能
- 工具栏添加排序按钮组,支持时间倒序/正序、名称倒序/正序 - 排序设置保存到本地,应用重启后恢复默认排序方式 - 排序菜单显示当前选中的排序方法(带勾选标记) - 修复置顶图片排序,保留原有排序顺序排在前面
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Sun Apr 26 10:16:07 HKT 2026
|
#Sun Apr 26 11:00:35 CST 2026
|
||||||
stageCount=5
|
stageCount=5
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.0
|
baseVersion=15.0
|
||||||
publishVersion=15.0.4
|
publishVersion=15.0.4
|
||||||
buildCount=0
|
buildCount=5
|
||||||
baseBetaVersion=15.0.5
|
baseBetaVersion=15.0.5
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class AlbumActivity extends AppCompatActivity {
|
|||||||
private String albumPath;
|
private String albumPath;
|
||||||
private String albumName;
|
private String albumName;
|
||||||
private FloatingActionButton fabScrollTop;
|
private FloatingActionButton fabScrollTop;
|
||||||
private RecyclerView.OnScrollListener scrollListener;
|
private Preferences prefs;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -49,6 +49,8 @@ public class AlbumActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
getSupportActionBar().setTitle(albumName);
|
getSupportActionBar().setTitle(albumName);
|
||||||
|
|
||||||
|
prefs = new Preferences(this);
|
||||||
|
|
||||||
recyclerView = findViewById(R.id.recycler_view);
|
recyclerView = findViewById(R.id.recycler_view);
|
||||||
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
|
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
|
||||||
adapter = new ImageAdapter();
|
adapter = new ImageAdapter();
|
||||||
@@ -63,7 +65,7 @@ public class AlbumActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollListener = new RecyclerView.OnScrollListener() {
|
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
super.onScrolled(recyclerView, dx, dy);
|
||||||
@@ -77,8 +79,7 @@ public class AlbumActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
recyclerView.addOnScrollListener(scrollListener);
|
|
||||||
|
|
||||||
adapter.setOnImageClickListener(new OnImageClickListener() {
|
adapter.setOnImageClickListener(new OnImageClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -122,6 +123,20 @@ public class AlbumActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getSortOrder(int sortMode) {
|
||||||
|
switch (sortMode) {
|
||||||
|
case Preferences.SORT_TIME_ASC:
|
||||||
|
return android.provider.MediaStore.Images.Media.DATE_ADDED + " ASC";
|
||||||
|
case Preferences.SORT_NAME_DESC:
|
||||||
|
return android.provider.MediaStore.Images.Media.DISPLAY_NAME + " DESC";
|
||||||
|
case Preferences.SORT_NAME_ASC:
|
||||||
|
return android.provider.MediaStore.Images.Media.DISPLAY_NAME + " ASC";
|
||||||
|
case Preferences.SORT_TIME_DESC:
|
||||||
|
default:
|
||||||
|
return android.provider.MediaStore.Images.Media.DATE_ADDED + " DESC";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void loadImages() {
|
private void loadImages() {
|
||||||
LogUtils.d(TAG, "loadImages");
|
LogUtils.d(TAG, "loadImages");
|
||||||
ArrayList<Uri> imageUrls = new ArrayList<>();
|
ArrayList<Uri> imageUrls = new ArrayList<>();
|
||||||
@@ -131,7 +146,8 @@ public class AlbumActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
String selection = android.provider.MediaStore.Images.Media.DATA + " LIKE ?";
|
String selection = android.provider.MediaStore.Images.Media.DATA + " LIKE ?";
|
||||||
String[] selectionArgs = new String[]{albumPath + "%"};
|
String[] selectionArgs = new String[]{albumPath + "%"};
|
||||||
String sortOrder = android.provider.MediaStore.Images.Media.DATE_ADDED + " DESC";
|
int sortMode = prefs.getAlbumSortMode();
|
||||||
|
String sortOrder = getSortOrder(sortMode);
|
||||||
|
|
||||||
try (Cursor cursor = contentResolver.query(collection, null, selection, selectionArgs, sortOrder)) {
|
try (Cursor cursor = contentResolver.query(collection, null, selection, selectionArgs, sortOrder)) {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
@@ -156,6 +172,63 @@ public class AlbumActivity extends AppCompatActivity {
|
|||||||
LogUtils.d(TAG, "Loaded " + imageUrls.size() + " images");
|
LogUtils.d(TAG, "Loaded " + imageUrls.size() + " images");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.menu_album, menu);
|
||||||
|
int sortMode = prefs.getAlbumSortMode();
|
||||||
|
int menuId = getSortMenuId(sortMode);
|
||||||
|
MenuItem item = menu.findItem(menuId);
|
||||||
|
if (item != null) {
|
||||||
|
item.setChecked(true);
|
||||||
|
}
|
||||||
|
MenuItem sortItem = menu.findItem(R.id.action_sort);
|
||||||
|
if (sortItem != null && sortItem.getSubMenu() != null) {
|
||||||
|
sortItem.getSubMenu().setGroupCheckable(0, true, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSortMenuId(int sortMode) {
|
||||||
|
switch (sortMode) {
|
||||||
|
case Preferences.SORT_TIME_ASC:
|
||||||
|
return R.id.sort_time_asc;
|
||||||
|
case Preferences.SORT_NAME_DESC:
|
||||||
|
return R.id.sort_name_desc;
|
||||||
|
case Preferences.SORT_NAME_ASC:
|
||||||
|
return R.id.sort_name_asc;
|
||||||
|
case Preferences.SORT_TIME_DESC:
|
||||||
|
default:
|
||||||
|
return R.id.sort_time_desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
|
int itemId = item.getItemId();
|
||||||
|
if (itemId == R.id.sort_time_desc) {
|
||||||
|
prefs.setAlbumSortMode(Preferences.SORT_TIME_DESC);
|
||||||
|
item.setChecked(true);
|
||||||
|
loadImages();
|
||||||
|
return true;
|
||||||
|
} else if (itemId == R.id.sort_time_asc) {
|
||||||
|
prefs.setAlbumSortMode(Preferences.SORT_TIME_ASC);
|
||||||
|
item.setChecked(true);
|
||||||
|
loadImages();
|
||||||
|
return true;
|
||||||
|
} else if (itemId == R.id.sort_name_desc) {
|
||||||
|
prefs.setAlbumSortMode(Preferences.SORT_NAME_DESC);
|
||||||
|
item.setChecked(true);
|
||||||
|
loadImages();
|
||||||
|
return true;
|
||||||
|
} else if (itemId == R.id.sort_name_asc) {
|
||||||
|
prefs.setAlbumSortMode(Preferences.SORT_NAME_ASC);
|
||||||
|
item.setChecked(true);
|
||||||
|
loadImages();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|||||||
@@ -58,45 +58,27 @@ public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ViewHolder>
|
|||||||
if (pinnedDbHelper == null || imagePaths.isEmpty()) {
|
if (pinnedDbHelper == null || imagePaths.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ArrayList<Uri> pinnedUrls = new ArrayList<>();
|
||||||
ArrayList<String> pinnedPaths = new ArrayList<>();
|
ArrayList<String> pinnedPaths = new ArrayList<>();
|
||||||
|
ArrayList<Uri> unpinnedUrls = new ArrayList<>();
|
||||||
ArrayList<String> unpinnedPaths = new ArrayList<>();
|
ArrayList<String> unpinnedPaths = new ArrayList<>();
|
||||||
for (String path : imagePaths) {
|
for (int i = 0; i < imagePaths.size(); i++) {
|
||||||
|
String path = imagePaths.get(i);
|
||||||
if (pinnedDbHelper.isPinned(path)) {
|
if (pinnedDbHelper.isPinned(path)) {
|
||||||
|
pinnedUrls.add(imageUrls.get(i));
|
||||||
pinnedPaths.add(path);
|
pinnedPaths.add(path);
|
||||||
} else {
|
} else {
|
||||||
|
unpinnedUrls.add(imageUrls.get(i));
|
||||||
unpinnedPaths.add(path);
|
unpinnedPaths.add(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Comparator<String> pathComparator = new Comparator<String>() {
|
|
||||||
@Override
|
|
||||||
public int compare(String p1, String p2) {
|
|
||||||
return p1.compareToIgnoreCase(p2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Collections.sort(pinnedPaths, pathComparator);
|
|
||||||
Collections.sort(unpinnedPaths, pathComparator);
|
|
||||||
|
|
||||||
ArrayList<Uri> newUrls = new ArrayList<>();
|
|
||||||
ArrayList<String> newPaths = new ArrayList<>();
|
|
||||||
for (String path : pinnedPaths) {
|
|
||||||
int index = imagePaths.indexOf(path);
|
|
||||||
if (index >= 0) {
|
|
||||||
newUrls.add(imageUrls.get(index));
|
|
||||||
newPaths.add(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (String path : unpinnedPaths) {
|
|
||||||
int index = imagePaths.indexOf(path);
|
|
||||||
if (index >= 0) {
|
|
||||||
newUrls.add(imageUrls.get(index));
|
|
||||||
newPaths.add(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
imageUrls.clear();
|
imageUrls.clear();
|
||||||
imagePaths.clear();
|
imagePaths.clear();
|
||||||
imageUrls.addAll(newUrls);
|
imageUrls.addAll(pinnedUrls);
|
||||||
imagePaths.addAll(newPaths);
|
imageUrls.addAll(unpinnedUrls);
|
||||||
|
imagePaths.addAll(pinnedPaths);
|
||||||
|
imagePaths.addAll(unpinnedPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContext(android.content.Context context) {
|
public void setContext(android.content.Context context) {
|
||||||
|
|||||||
@@ -9,9 +9,16 @@ public class Preferences {
|
|||||||
private static final String PREF_NAME = "gallery_prefs";
|
private static final String PREF_NAME = "gallery_prefs";
|
||||||
private static final String KEY_FOLDER_PATH = "folder_path";
|
private static final String KEY_FOLDER_PATH = "folder_path";
|
||||||
private static final String KEY_BG_TYPE = "bg_type";
|
private static final String KEY_BG_TYPE = "bg_type";
|
||||||
|
private static final String KEY_ALBUM_SORT_MODE = "album_sort_mode";
|
||||||
private static final int DEFAULT_BG_TYPE = 0;
|
private static final int DEFAULT_BG_TYPE = 0;
|
||||||
|
private static final int DEFAULT_SORT_MODE = 0;
|
||||||
private static final String DEFAULT_PATH = "/storage/emulated/0/Pictures/Gallery/owner";
|
private static final String DEFAULT_PATH = "/storage/emulated/0/Pictures/Gallery/owner";
|
||||||
|
|
||||||
|
public static final int SORT_TIME_DESC = 0;
|
||||||
|
public static final int SORT_TIME_ASC = 1;
|
||||||
|
public static final int SORT_NAME_DESC = 2;
|
||||||
|
public static final int SORT_NAME_ASC = 3;
|
||||||
|
|
||||||
public static String getDefaultPath() {
|
public static String getDefaultPath() {
|
||||||
return DEFAULT_PATH;
|
return DEFAULT_PATH;
|
||||||
}
|
}
|
||||||
@@ -41,4 +48,13 @@ public class Preferences {
|
|||||||
LogUtils.d(TAG, "setBgType: " + type);
|
LogUtils.d(TAG, "setBgType: " + type);
|
||||||
prefs.edit().putInt(KEY_BG_TYPE, type).apply();
|
prefs.edit().putInt(KEY_BG_TYPE, type).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getAlbumSortMode() {
|
||||||
|
return prefs.getInt(KEY_ALBUM_SORT_MODE, DEFAULT_SORT_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlbumSortMode(int mode) {
|
||||||
|
LogUtils.d(TAG, "setAlbumSortMode: " + mode);
|
||||||
|
prefs.edit().putInt(KEY_ALBUM_SORT_MODE, mode).apply();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
10
gallery/src/main/res/drawable/ic_sort.xml
Normal file
10
gallery/src/main/res/drawable/ic_sort.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M3,18h6v-2H3v2zM3,6v2h18V6H3zM3,13h12v-2H3v2z"/>
|
||||||
|
</vector>
|
||||||
26
gallery/src/main/res/menu/menu_album.xml
Normal file
26
gallery/src/main/res/menu/menu_album.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_sort"
|
||||||
|
android:icon="@drawable/ic_sort"
|
||||||
|
android:title="排序"
|
||||||
|
app:showAsAction="ifRoom">
|
||||||
|
<menu>
|
||||||
|
<group android:checkableBehavior="single">
|
||||||
|
<item
|
||||||
|
android:id="@+id/sort_time_desc"
|
||||||
|
android:title="时间倒序"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/sort_time_asc"
|
||||||
|
android:title="时间正序"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/sort_name_desc"
|
||||||
|
android:title="名称倒序"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/sort_name_asc"
|
||||||
|
android:title="名称正序"/>
|
||||||
|
</group>
|
||||||
|
</menu>
|
||||||
|
</item>
|
||||||
|
</menu>
|
||||||
Reference in New Issue
Block a user