Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-deck.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2020-11-03 19:45:24 +0300
committerStefan Niedermann <info@niedermann.it>2020-11-03 19:45:24 +0300
commitce54a71de9d40f994078cb93b7e2e411b77dffef (patch)
tree17b81ee0fabdbc3227b3878a4f3d035901c27045 /app/src/main/java/it/niedermann/nextcloud/deck/ui
parent704b8c48d1fdfeee3d900287347d24e79a72aef8 (diff)
Allow actual image picking
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main/java/it/niedermann/nextcloud/deck/ui')
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java52
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java54
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryItemViewHolder.java14
3 files changed, 87 insertions, 33 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java
index 9edcf7a33..2401a4829 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java
@@ -92,6 +92,7 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
private CardAttachmentAdapter adapter;
private ImageView[] brandedViews;
+ private GalleryAdapter galleryAdapter;
private int clickedItemPosition;
@@ -152,15 +153,30 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case STATE_HIDDEN: {
+ DeckLog.log("BottomSheet: HIDDEN");
hidePicker();
binding.fab.show();
break;
}
- case STATE_EXPANDED:
+ case STATE_EXPANDED: {
+ DeckLog.log("BottomSheet: EXPANDED");
+ showPicker();
+ break;
+ }
case STATE_HALF_EXPANDED: {
+ DeckLog.log("BottomSheet: HALF_EXPANDED");
showPicker();
break;
}
+ case BottomSheetBehavior.STATE_COLLAPSED:
+ DeckLog.log("BottomSheet: COLLAPSED");
+ break;
+ case BottomSheetBehavior.STATE_DRAGGING:
+ DeckLog.log("BottomSheet: DRAGGING");
+ break;
+ case BottomSheetBehavior.STATE_SETTLING:
+ DeckLog.log("BottomSheet: SETTLING");
+ break;
}
}
@@ -169,11 +185,6 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
}
});
- if (SDK_INT >= LOLLIPOP) {
- GalleryAdapter galleryAdapter = new GalleryAdapter(requireContext());
- binding.pickerRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3));
- binding.pickerRecyclerView.setAdapter(galleryAdapter);
- }
final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int spanCount = (int) ((displayMetrics.widthPixels / displayMetrics.density) / getResources().getInteger(R.integer.max_dp_attachment_column));
@@ -209,9 +220,15 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
if (viewModel.canEdit()) {
binding.fab.setOnClickListener(v -> {
-// picker = CardAttachmentPicker.newInstance();
-// picker.show(getChildFragmentManager(), CardAttachmentPicker.class.getSimpleName());
- mBottomSheetBehaviour.setState(STATE_HALF_EXPANDED);
+ if (SDK_INT >= LOLLIPOP && galleryAdapter == null) {
+ galleryAdapter = new GalleryAdapter(requireContext(), uri -> {
+ // TODO show selected image in dialog and let it confirm first
+ onActivityResult(REQUEST_CODE_ADD_FILE, RESULT_OK, new Intent().setData(uri));
+ });
+ binding.pickerRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3));
+ binding.pickerRecyclerView.setAdapter(galleryAdapter);
+ }
+ mBottomSheetBehaviour.setState(STATE_EXPANDED);
showPicker();
binding.fab.hide();
});
@@ -314,6 +331,15 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
}
}
+ @Override
+ public void onDestroy() {
+ if (this.galleryAdapter != null) {
+ this.galleryAdapter.onDestroy();
+ this.binding.pickerRecyclerView.setAdapter(null);
+ }
+ super.onDestroy();
+ }
+
private void uploadNewAttachmentFromUri(@NonNull Uri sourceUri, String mimeType) throws UploadAttachmentFailedException, IOException {
if (sourceUri == null) {
throw new UploadAttachmentFailedException("sourceUri is null");
@@ -408,6 +434,14 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme
}
}
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ if (galleryAdapter != null) {
+ galleryAdapter.onLowMemory();
+ }
+ }
+
private void hidePicker() {
binding.bottomNavigation
.animate()
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java
index d123cee74..0b051ed58 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java
@@ -6,6 +6,7 @@ import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
+import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;
@@ -13,10 +14,8 @@ import android.util.Pair;
import android.util.Size;
import android.view.LayoutInflater;
import android.view.ViewGroup;
-import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import java.util.HashMap;
@@ -27,8 +26,8 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
+import java.util.function.Consumer;
-import it.niedermann.nextcloud.deck.DeckLog;
import it.niedermann.nextcloud.deck.databinding.ItemAttachmentImageBinding;
import static android.os.Build.VERSION.SDK_INT;
@@ -37,38 +36,37 @@ import static androidx.recyclerview.widget.RecyclerView.NO_ID;
public class GalleryAdapter extends RecyclerView.Adapter<GalleryItemViewHolder> {
- @NonNull
- private final Context context;
private final int columnIndex;
private final int count;
- @Nullable
+ @NonNull
+ private final Consumer<Uri> onSelect;
+ @NonNull
private final Cursor cursor;
@NonNull
private final ContentResolver contentResolver;
@NonNull
private final Map<Integer, Pair<Long, FutureTask<Bitmap>>> itemCache = new HashMap<>();
+ @NonNull
private final ExecutorService bitmapFetcherExecutor = Executors.newCachedThreadPool();
+ @NonNull
private final ExecutorService bitmapWaiterExecutor = Executors.newCachedThreadPool();
- public GalleryAdapter(@NonNull Context context) {
- this.context = context;
+ public GalleryAdapter(@NonNull Context context, @NonNull Consumer<Uri> onSelect) {
+ this.onSelect = onSelect;
this.contentResolver = context.getContentResolver();
- log("Start Query");
@SuppressLint("InlinedApi") final String sortOrder = (SDK_INT >= Q)
? MediaStore.Images.Media.DATE_TAKEN
: MediaStore.Images.Media.DATE_ADDED;
cursor = Objects.requireNonNull(contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media._ID}, null, null, sortOrder + " DESC"));
this.columnIndex = cursor.getColumnIndex(MediaStore.Images.Media._ID);
this.count = cursor.getCount();
-
- log("Cursor count = " + this.count);
notifyItemRangeInserted(0, this.count);
setHasStableIds(true);
}
@Override
public long getItemId(int position) {
- Pair<Long, ?> itemAtPosition = getImageId(position);
+ final Pair<Long, ?> itemAtPosition = getImageInformation(position);
return itemAtPosition == null ? NO_ID : itemAtPosition.first;
}
@@ -80,14 +78,15 @@ public class GalleryAdapter extends RecyclerView.Adapter<GalleryItemViewHolder>
@Override
public void onBindViewHolder(@NonNull GalleryItemViewHolder holder, int position) {
- FutureTask<Bitmap> imageFuture = getImageId(position).second;
- bitmapFetcherExecutor.execute(imageFuture);
+ final Pair<Long, FutureTask<Bitmap>> imageInformation = getImageInformation(position);
+ bitmapFetcherExecutor.execute(imageInformation.second);
bitmapWaiterExecutor.execute(() -> {
try {
- final Bitmap image = imageFuture.get();
- new Handler(Looper.getMainLooper()).post(() -> holder.bind(image));
+ final Bitmap image = imageInformation.second.get();
+ new Handler(Looper.getMainLooper()).post(() -> holder.bind(ContentUris.withAppendedId(
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageInformation.first), image, onSelect));
} catch (ExecutionException | InterruptedException ignored) {
- new Handler(Looper.getMainLooper()).post(() -> holder.bind(null));
+ new Handler(Looper.getMainLooper()).post(holder::bindError);
}
});
}
@@ -97,12 +96,12 @@ public class GalleryAdapter extends RecyclerView.Adapter<GalleryItemViewHolder>
return count;
}
- private Pair<Long, FutureTask<Bitmap>> getImageId(int position) {
+ private Pair<Long, FutureTask<Bitmap>> getImageInformation(int position) {
if (itemCache.containsKey(position)) {
return itemCache.get(position);
} else {
- if (cursor == null) {
- return new Pair<>(NO_ID, null);
+ if (cursor.isClosed()) {
+ throw new IllegalStateException("This adapter has already been destoryed and can no longer be used.");
}
if (cursor.moveToPosition(position)) {
long id = cursor.getLong(columnIndex);
@@ -122,8 +121,17 @@ public class GalleryAdapter extends RecyclerView.Adapter<GalleryItemViewHolder>
}
}
- private void log(String msg) {
- DeckLog.log(msg);
- Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+ /**
+ * Call this method in case of low memory. It will clear the internally cached {@link Bitmap}s to free memory.
+ */
+ public void onLowMemory() {
+ itemCache.clear();
+ }
+
+ /**
+ * Call this method when the {@link GalleryAdapter} is no longe need to free resources.
+ */
+ public void onDestroy() {
+ cursor.close();
}
}
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryItemViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryItemViewHolder.java
index 7c4cf4a5a..d83876f0e 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryItemViewHolder.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryItemViewHolder.java
@@ -1,6 +1,7 @@
package it.niedermann.nextcloud.deck.ui.card.attachments.picker;
import android.graphics.Bitmap;
+import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -10,7 +11,9 @@ import com.bumptech.glide.Glide;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.function.Consumer;
+import it.niedermann.nextcloud.deck.R;
import it.niedermann.nextcloud.deck.databinding.ItemAttachmentImageBinding;
public class GalleryItemViewHolder extends RecyclerView.ViewHolder {
@@ -23,9 +26,18 @@ public class GalleryItemViewHolder extends RecyclerView.ViewHolder {
this.binding = binding;
}
- public void bind(@Nullable Bitmap image) {
+ public void bind(@NonNull Uri uri, @Nullable Bitmap image, @NonNull Consumer<Uri> onSelect) {
+ itemView.setOnClickListener((v) -> onSelect.accept(uri));
Glide.with(itemView.getContext())
.load(image)
+ .placeholder(R.drawable.ic_image_grey600_24dp)
+ .into(binding.preview);
+ }
+
+ public void bindError() {
+ itemView.setOnClickListener(null);
+ Glide.with(itemView.getContext())
+ .load(R.drawable.ic_image_grey600_24dp)
.into(binding.preview);
}
}