diff options
author | stefan-niedermann <info@niedermann.it> | 2020-03-07 21:24:43 +0300 |
---|---|---|
committer | stefan-niedermann <info@niedermann.it> | 2020-03-07 21:24:43 +0300 |
commit | f180824ec20453fe281d859bdd04aac53684ae16 (patch) | |
tree | c635b2ce5e2b2a5ad54f395970b5b120d35f21d1 | |
parent | 656f1d4cc1596a7b6b5fc4b2aa28d8726956acc7 (diff) |
Make attachment viewer swipeable
11 files changed, 141 insertions, 45 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java index 411acdb90..93799e138 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java @@ -4,8 +4,7 @@ import android.os.Bundle; import android.view.MotionEvent; import androidx.appcompat.app.AppCompatActivity; - -import com.bumptech.glide.Glide; +import androidx.recyclerview.widget.RecyclerView; import java.util.List; @@ -13,8 +12,8 @@ import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.databinding.ActivityAttachmentsBinding; import it.niedermann.nextcloud.deck.model.Attachment; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; +import it.niedermann.nextcloud.deck.ui.attachments.AttachmentAdapter; import it.niedermann.nextcloud.deck.ui.exception.ExceptionHandler; -import it.niedermann.nextcloud.deck.util.AttachmentUtil; import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_ACCOUNT_ID; import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_LOCAL_ID; @@ -51,26 +50,34 @@ public class AttachmentsActivity extends AppCompatActivity { List<Attachment> attachments = fullCard.getAttachments(); if (fullCard.getAttachments().size() == 0) { DeckLog.logError(new IllegalStateException(AttachmentsActivity.class.getSimpleName() + " called, but card " + fullCard.getLocalId() + "has no attachments")); - finish(); - } else { - if (currentAttachment != 0L) { - for (Attachment a : attachments) { - if (a.getLocalId() == currentAttachment) { - Glide.with(this) - .load(AttachmentUtil.getUrl(account.getUrl(), fullCard.getId(), a.getId())) - .into(binding.image); - binding.toolbar.setTitle(a.getBasename()); - break; - } + supportFinishAfterTransition(); + return; + } + RecyclerView.Adapter adapter = new AttachmentAdapter(account, fullCard.getId(), attachments); + binding.viewPager.setAdapter(adapter); + if (currentAttachment != 0L) { + for (int i = 0; i < attachments.size(); i++) { + if (attachments.get(i).getLocalId() == currentAttachment) { + binding.viewPager.setCurrentItem(i, false); + break; } - } else { - DeckLog.logError(new IllegalStateException("No " + BUNDLE_KEY_CURRENT_ATTACHMENT_LOCAL_ID + " was provided. Falling back to displaying first image.")); - Glide.with(this) - .load(AttachmentUtil.getUrl(account.getUrl(), fullCard.getId(), attachments.get(0).getId())) - .into(binding.image); - binding.toolbar.setTitle(attachments.get(0).getBasename()); } } + // TODO + // https://android-developers.googleblog.com/2018/02/continuous-shared-element-transitions.html?m=1 + // https://github.com/android/animation-samples/blob/master/GridToPager/app/src/main/java/com/google/samples/gridtopager/fragment/ImagePagerFragment.java +// setEnterSharedElementCallback(new SharedElementCallback() { +// @Override +// public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { +// View view = binding.viewPager.getRootView(); +// if (view == null) { +// return; +// } +// // Map the first shared element name to the child ImageView. +// sharedElements.put(names.get(0), view.findViewById(R.id.image)); +// Log.v("SHARED", "names" + names); +// } +// }); })); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentAdapter.java new file mode 100644 index 000000000..1d7307ccd --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentAdapter.java @@ -0,0 +1,74 @@ +package it.niedermann.nextcloud.deck.ui.attachments; + +import android.content.Context; +import android.os.Build; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; + +import java.util.List; + +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.databinding.ItemAttachmentBinding; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Attachment; +import it.niedermann.nextcloud.deck.util.AttachmentUtil; + +public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.AttachmentViewHolder> { + + private final Account account; + private final long cardRemoteId; + @NonNull + private List<Attachment> attachments; + private Context context; + + public AttachmentAdapter(@NonNull Account account, long cardRemoteId, @NonNull List<Attachment> attachments) { + super(); + this.attachments = attachments; + this.account = account; + this.cardRemoteId = cardRemoteId; + } + + @NonNull + @Override + public AttachmentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + this.context = parent.getContext(); + return new AttachmentViewHolder(ItemAttachmentBinding.inflate(LayoutInflater.from(context), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull AttachmentViewHolder holder, int position) { + Attachment attachment = attachments.get(position); + String uri = AttachmentUtil.getUrl(account.getUrl(), cardRemoteId, attachment.getId()); + if (attachment.getMimetype() != null) { + if (attachment.getMimetype().startsWith("image")) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + holder.binding.preview.setTransitionName(context.getString(R.string.transition_attachment_preview, String.valueOf(attachment.getLocalId()))); + } + holder.binding.preview.setImageResource(R.drawable.ic_image_grey600_24dp); + Glide.with(context) + .load(uri) + .error(R.drawable.ic_image_grey600_24dp) + .into(holder.binding.preview); + } + } + } + + @Override + public int getItemCount() { + return attachments.size(); + } + + static class AttachmentViewHolder extends RecyclerView.ViewHolder { + private ItemAttachmentBinding binding; + + private AttachmentViewHolder(ItemAttachmentBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/ActivityAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityAdapter.java index ab43b7634..b2a8a7aa4 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/ActivityAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityAdapter.java @@ -15,13 +15,13 @@ import it.niedermann.nextcloud.deck.model.enums.ActivityType; import it.niedermann.nextcloud.deck.model.ocs.Activity; import it.niedermann.nextcloud.deck.util.DateUtil; -public class ActivityAdapter extends RecyclerView.Adapter<ActivityAdapter.ActivitiesViewHolder> { +public class CardActivityAdapter extends RecyclerView.Adapter<CardActivityAdapter.ActivitiesViewHolder> { @NonNull private List<Activity> activities; private Context context; - public ActivityAdapter(@NonNull List<Activity> activities) { + public CardActivityAdapter(@NonNull List<Activity> activities) { super(); this.activities = activities; } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityFragment.java index c2bcad532..9c4aaf5c2 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityFragment.java @@ -70,7 +70,7 @@ public class CardActivityFragment extends Fragment { } else { binding.emptyContentView.setVisibility(View.GONE); binding.activitiesList.setVisibility(View.VISIBLE); - RecyclerView.Adapter adapter = new ActivityAdapter(activities); + RecyclerView.Adapter adapter = new CardActivityAdapter(activities); binding.activitiesList.setAdapter(adapter); } })); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentAdapter.java index 7cd953787..7b07abbfd 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentAdapter.java @@ -8,7 +8,6 @@ import android.content.Intent; import android.net.Uri; import android.os.Build; import android.text.format.Formatter; -import android.transition.Explode; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuInflater; @@ -42,7 +41,7 @@ import static it.niedermann.nextcloud.deck.ui.AttachmentsActivity.BUNDLE_KEY_CUR import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_ACCOUNT_ID; import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_LOCAL_ID; -public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.AttachmentViewHolder> { +public class CardAttachmentAdapter extends RecyclerView.Adapter<CardAttachmentAdapter.AttachmentViewHolder> { public static final int VIEW_TYPE_DEFAULT = 2; public static final int VIEW_TYPE_IMAGE = 1; @@ -57,7 +56,7 @@ public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.At private AttachmentDeletedListener attachmentDeletedListener; private Context context; - AttachmentAdapter(@NonNull MenuInflater menuInflator, @NonNull AttachmentDeletedListener attachmentDeletedListener, @NonNull Account account, long cardLocalId, long cardRemoteId, @NonNull List<Attachment> attachments) { + CardAttachmentAdapter(@NonNull MenuInflater menuInflator, @NonNull AttachmentDeletedListener attachmentDeletedListener, @NonNull Account account, long cardLocalId, long cardRemoteId, @NonNull List<Attachment> attachments) { super(); this.menuInflator = menuInflator; this.attachmentDeletedListener = attachmentDeletedListener; @@ -126,8 +125,9 @@ public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.At intent.putExtra(BUNDLE_KEY_CURRENT_ATTACHMENT_LOCAL_ID, attachment.getLocalId()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && context instanceof Activity) { - ((Activity) context).getWindow().setSharedElementEnterTransition(new Explode()); - context.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) context, holder.getPreview(), context.getString(R.string.transition_attachment_preview)).toBundle()); + String transitionName = context.getString(R.string.transition_attachment_preview, String.valueOf(attachment.getLocalId())); + holder.getPreview().setTransitionName(transitionName); + context.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) context, holder.getPreview(), transitionName).toBundle()); } else { context.startActivity(intent); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java index 33e5a6306..875ecb281 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java @@ -31,7 +31,7 @@ import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_BOARD_ import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_CAN_EDIT; import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_LOCAL_ID; -public class CardAttachmentsFragment extends Fragment implements AttachmentAdapter.AttachmentDeletedListener { +public class CardAttachmentsFragment extends Fragment implements CardAttachmentAdapter.AttachmentDeletedListener { private static final String TAG = CardAttachmentsFragment.class.getCanonicalName(); private FragmentCardEditTabAttachmentsBinding binding; @@ -66,7 +66,7 @@ public class CardAttachmentsFragment extends Fragment implements AttachmentAdapt this.binding.emptyContentView.setVisibility(View.GONE); this.binding.attachmentsList.setVisibility(View.VISIBLE); syncManager.readAccount(accountId).observe(getViewLifecycleOwner(), (Account account) -> { - RecyclerView.Adapter adapter = new AttachmentAdapter( + RecyclerView.Adapter adapter = new CardAttachmentAdapter( requireActivity().getMenuInflater(), this, account, @@ -74,15 +74,25 @@ public class CardAttachmentsFragment extends Fragment implements AttachmentAdapt fullCard.getCard().getId(), fullCard.getAttachments()); binding.attachmentsList.setAdapter(adapter); + + // TODO + // https://android-developers.googleblog.com/2018/02/continuous-shared-element-transitions.html?m=1 + // https://github.com/android/animation-samples/blob/master/GridToPager/app/src/main/java/com/google/samples/gridtopager/fragment/ImagePagerFragment.java +// setExitSharedElementCallback(new SharedElementCallback() { +// @Override +// public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { +// Log.v("SHARED", "names" + names); +// } +// }); GridLayoutManager glm = new GridLayoutManager(getActivity(), 3); glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { switch (adapter.getItemViewType(position)) { - case AttachmentAdapter.VIEW_TYPE_IMAGE: + case CardAttachmentAdapter.VIEW_TYPE_IMAGE: return 1; - case AttachmentAdapter.VIEW_TYPE_DEFAULT: + case CardAttachmentAdapter.VIEW_TYPE_DEFAULT: return 3; default: return 1; @@ -94,7 +104,7 @@ public class CardAttachmentsFragment extends Fragment implements AttachmentAdapt } }); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && canEdit) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && canEdit) { binding.fab.setOnClickListener(v -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, diff --git a/app/src/main/res/layout/activity_attachments.xml b/app/src/main/res/layout/activity_attachments.xml index 4d1fabe17..2e9f68414 100644 --- a/app/src/main/res/layout/activity_attachments.xml +++ b/app/src/main/res/layout/activity_attachments.xml @@ -23,14 +23,14 @@ <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_width="match_parent" - android:layout_height="wrap_content" /> + android:layout_height="match_parent" /> - <androidx.appcompat.widget.AppCompatImageView - android:id="@+id/image" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:contentDescription="@null" - android:transitionName="@string/transition_attachment_preview" - tools:src="@drawable/ic_image_grey600_24dp" - tools:targetApi="lollipop" /> +<!-- <androidx.appcompat.widget.AppCompatImageView--> +<!-- android:id="@+id/image"--> +<!-- android:layout_width="match_parent"--> +<!-- android:layout_height="match_parent"--> +<!-- android:contentDescription="@null"--> +<!-- android:transitionName="@string/transition_attachment_preview"--> +<!-- tools:src="@drawable/ic_image_grey600_24dp"--> +<!-- tools:targetApi="lollipop" />--> </LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_attachment.xml b/app/src/main/res/layout/item_attachment.xml new file mode 100644 index 000000000..08a31cf7d --- /dev/null +++ b/app/src/main/res/layout/item_attachment.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.appcompat.widget.AppCompatImageView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/preview" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:srcCompat="@drawable/ic_image_grey600_24dp" />
\ No newline at end of file diff --git a/app/src/main/res/layout/item_attachment_default.xml b/app/src/main/res/layout/item_attachment_default.xml index 11d147d92..f58783559 100644 --- a/app/src/main/res/layout/item_attachment_default.xml +++ b/app/src/main/res/layout/item_attachment_default.xml @@ -20,7 +20,6 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="@dimen/standard_half_margin" - android:transitionName="@string/transition_attachment_preview" app:srcCompat="@drawable/ic_attach_file_grey600_24dp" /> <androidx.appcompat.widget.AppCompatImageView diff --git a/app/src/main/res/layout/item_attachment_image.xml b/app/src/main/res/layout/item_attachment_image.xml index 42ab7bc66..476b7497d 100644 --- a/app/src/main/res/layout/item_attachment_image.xml +++ b/app/src/main/res/layout/item_attachment_image.xml @@ -12,7 +12,6 @@ android:layout_height="match_parent" android:layout_gravity="center" android:scaleType="centerCrop" - android:transitionName="@string/transition_attachment_preview" app:srcCompat="@drawable/ic_image_grey600_24dp" /> <androidx.appcompat.widget.AppCompatImageView diff --git a/app/src/main/res/values/setup.xml b/app/src/main/res/values/setup.xml index db81c60a1..567f06b3a 100644 --- a/app/src/main/res/values/setup.xml +++ b/app/src/main/res/values/setup.xml @@ -35,5 +35,5 @@ <integer name="minimum_server_app_patch" translatable="false">4</integer> <!-- Transitions --> - <string name="transition_attachment_preview" translatable="false">transition_attachment_preview</string> + <string name="transition_attachment_preview" translatable="false">transition_attachment_preview_%1$s</string> </resources>
\ No newline at end of file |