1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
package it.niedermann.nextcloud.deck.ui.card.attachments.picker;
import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;
import android.util.Pair;
import android.util.Size;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.RequestBuilder;
import java.io.IOException;
import java.util.function.BiConsumer;
import it.niedermann.nextcloud.deck.databinding.ItemAttachmentImageBinding;
import it.niedermann.nextcloud.deck.databinding.ItemPhotoPreviewBinding;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.Q;
import static android.provider.BaseColumns._ID;
import static android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
public class GalleryAdapter extends AbstractCursorPickerAdapter<RecyclerView.ViewHolder> {
@NonNull
private final LifecycleOwner lifecycleOwner;
@SuppressLint("InlinedApi")
private static final String sortOrder = (SDK_INT >= Q)
? MediaStore.Images.Media.DATE_TAKEN
: MediaStore.Images.Media.DATE_ADDED;
public GalleryAdapter(@NonNull Context context, @NonNull BiConsumer<Uri, Pair<String, RequestBuilder<?>>> onSelect, @NonNull Runnable openNativePicker, @NonNull LifecycleOwner lifecycleOwner) {
super(context, onSelect, openNativePicker, EXTERNAL_CONTENT_URI, _ID, sortOrder + " DESC");
this.lifecycleOwner = lifecycleOwner;
notifyItemRangeInserted(0, getItemCount() + 1);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_ITEM_NATIVE:
return new GalleryPhotoPreviewItemViewHolder(ItemPhotoPreviewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
case VIEW_TYPE_ITEM:
return new GalleryItemViewHolder(ItemAttachmentImageBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
default:
throw new IllegalStateException("Unknown viewType " + viewType);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case VIEW_TYPE_ITEM_NATIVE: {
((GalleryPhotoPreviewItemViewHolder) holder).bind(openNativePicker, lifecycleOwner);
break;
}
case VIEW_TYPE_ITEM: {
final long id = getItemId(position);
if (!bindExecutor.isTerminated()) {
bindExecutor.execute(() -> {
try {
final Bitmap thumbnail;
if (SDK_INT >= Q) {
thumbnail = contentResolver.loadThumbnail(ContentUris.withAppendedId(
EXTERNAL_CONTENT_URI, id), new Size(512, 384), null);
} else {
thumbnail = MediaStore.Images.Thumbnails.getThumbnail(
contentResolver, id,
MediaStore.Images.Thumbnails.MINI_KIND, null);
}
new Handler(Looper.getMainLooper()).post(() -> ((GalleryItemViewHolder) holder).bind(ContentUris.withAppendedId(
EXTERNAL_CONTENT_URI, id), thumbnail, onSelect));
} catch (IOException ignored) {
new Handler(Looper.getMainLooper()).post(((GalleryItemViewHolder) holder)::bindError);
}
});
}
}
}
}
@Override
public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
super.onViewDetachedFromWindow(holder);
if (holder instanceof GalleryPhotoPreviewItemViewHolder) {
((GalleryPhotoPreviewItemViewHolder) holder).unbind();
}
}
}
|