Files
WinBoLL/gallery/src/main/java/cc/winboll/studio/gallery/AlbumAdapter.java
ZhanGSKen 4d0d8c4d59 添加相册集置顶功能
- 长按相册封面显示菜单,可选择置顶
- 置顶的相册优先显示并按名称排序
- 非置顶的相册也按名称排序
- 置顶图标显示在封面上
2026-04-26 09:06:27 +08:00

230 lines
8.4 KiB
Java

package cc.winboll.studio.gallery;
import android.net.Uri;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import cc.winboll.studio.libappbase.LogUtils;
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder> {
public static final String TAG = "AlbumAdapter";
private ArrayList<Album> albums = new ArrayList<>();
private OnAlbumClickListener listener;
private Preferences prefs;
private int bgType = 0;
private PinnedAlbumDbHelper pinnedDbHelper;
private int getBgRes() {
switch (bgType) {
case 0:
return R.drawable.bg_checkerboard;
case 1:
return R.drawable.bg_white;
case 2:
return R.drawable.bg_black;
default:
return R.drawable.bg_checkerboard;
}
}
public interface OnAlbumClickListener {
void onAlbumClick(Album album);
}
public void setOnAlbumClickListener(OnAlbumClickListener listener) {
this.listener = listener;
}
public void setData(ArrayList<Album> albums) {
this.albums = sortAlbums(albums);
LogUtils.d(TAG, "setData: " + albums.size() + " albums");
notifyDataSetChanged();
}
private ArrayList<Album> sortAlbums(ArrayList<Album> list) {
if (pinnedDbHelper == null || list == null || list.isEmpty()) {
return list;
}
ArrayList<Album> pinned = new ArrayList<>();
ArrayList<Album> unpinned = new ArrayList<>();
for (Album album : list) {
if (pinnedDbHelper.isPinned(album.getPath())) {
pinned.add(album);
} else {
unpinned.add(album);
}
}
pinned.addAll(unpinned);
return pinned;
}
public void setContext(android.content.Context context) {
prefs = new Preferences(context);
bgType = prefs.getBgType();
pinnedDbHelper = PinnedAlbumDbHelper.getInstance(context);
}
public void refreshBg() {
if (prefs != null) {
bgType = prefs.getBgType();
}
notifyDataSetChanged();
}
public void refreshPinned() {
if (pinnedDbHelper != null && albums != null && !albums.isEmpty()) {
ArrayList<Album> pinned = new ArrayList<>();
ArrayList<Album> unpinned = new ArrayList<>();
for (Album album : albums) {
if (pinnedDbHelper.isPinned(album.getPath())) {
pinned.add(album);
} else {
unpinned.add(album);
}
}
Comparator<Album> nameComparator = new Comparator<Album>() {
@Override
public int compare(Album a1, Album a2) {
return a1.getName().compareToIgnoreCase(a2.getName());
}
};
Collections.sort(pinned, nameComparator);
Collections.sort(unpinned, nameComparator);
albums.clear();
albums.addAll(pinned);
albums.addAll(unpinned);
notifyDataSetChanged();
}
}
private void showContextMenu(View view, final Album album) {
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(view.getContext());
builder.setTitle(album.getName());
boolean isPinned = pinnedDbHelper != null && pinnedDbHelper.isPinned(album.getPath());
String[] items = isPinned ? new String[]{"取消置顶"} : new String[]{"置顶"};
builder.setItems(items, new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(android.content.DialogInterface dialog, int which) {
if (pinnedDbHelper != null) {
if (which == 0) {
if (isPinned) {
pinnedDbHelper.unpinAlbum(album.getPath());
} else {
pinnedDbHelper.pinAlbum(album.getPath());
}
refreshPinned();
}
}
}
});
builder.show();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_album, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
final Album album = albums.get(position);
LogUtils.d(TAG, "bind: " + album.getName() + ", cover=" + album.getCoverUri());
holder.coverImage.setBackgroundResource(getBgRes());
boolean isPinned = pinnedDbHelper != null && pinnedDbHelper.isPinned(album.getPath());
holder.pinIcon.setVisibility(isPinned ? View.VISIBLE : View.GONE);
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
showContextMenu(holder.itemView, album);
return true;
}
});
holder.albumName.setText(album.getName());
holder.imageCount.setText(album.getImageCount() + " photos");
holder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onAlbumClick(album);
}
}
});
Uri coverUri = album.getCoverUri();
if (coverUri != null) {
String uriString = coverUri.toString();
LogUtils.d(TAG, "uri scheme: " + coverUri.getScheme() + ", path: " + uriString);
// For content:// URIs, try to get the actual file path
if ("content".equals(coverUri.getScheme())) {
try {
android.database.Cursor cursor = holder.coverImage.getContext().getContentResolver()
.query(coverUri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int dataColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
String filePath = cursor.getString(dataColumn);
cursor.close();
if (filePath != null) {
File actualFile = new File(filePath);
LogUtils.d(TAG, "actual file: " + actualFile.getAbsolutePath() + ", exists=" + actualFile.exists());
// Use file path instead of content URI for better compatibility
Glide.with(holder.coverImage.getContext())
.load(actualFile)
.centerCrop()
.into(holder.coverImage);
return;
}
}
} catch (Exception e) {
LogUtils.e(TAG, "query error: " + e.getMessage());
}
}
}
// Fallback to content URI
Glide.with(holder.coverImage.getContext())
.load(coverUri)
.centerCrop()
.into(holder.coverImage);
}
@Override
public int getItemCount() {
return albums.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView coverImage;
ImageView pinIcon;
TextView albumName;
TextView imageCount;
ViewHolder(View itemView) {
super(itemView);
coverImage = itemView.findViewById(R.id.album_cover);
pinIcon = itemView.findViewById(R.id.pin_icon);
albumName = itemView.findViewById(R.id.album_name);
imageCount = itemView.findViewById(R.id.image_count);
}
}
}