diff options
author | Stefan Niedermann <info@niedermann.it> | 2020-11-02 16:46:56 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2020-11-02 16:46:56 +0300 |
commit | 83bdf142473f857c93731f252aab2a183bd0f151 (patch) | |
tree | 5bb7f633fbada435ffa2dbb612ed27d7ff13b5dd /app/src/main/java/it/niedermann/nextcloud/deck/ui | |
parent | 56ca6c8969f3901ca8777284bf95985e7eadd315 (diff) |
Display images from gallery inline
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main/java/it/niedermann/nextcloud/deck/ui')
5 files changed, 151 insertions, 26 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentAdapter.java index d062bc827..d601f6bbd 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentAdapter.java @@ -41,7 +41,7 @@ public class CardAttachmentAdapter extends RecyclerView.Adapter<AttachmentViewHo public static final int VIEW_TYPE_IMAGE = 1; @NonNull - private MutableLiveData<Boolean> isEmpty = new MutableLiveData<>(true); + private final MutableLiveData<Boolean> isEmpty = new MutableLiveData<>(true); @NonNull private final MenuInflater menuInflater; @ColorInt 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 d528dc903..4a55a3203 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 @@ -2,31 +2,36 @@ package it.niedermann.nextcloud.deck.ui.card.attachments; import android.content.ContentResolver; import android.content.Intent; +import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; +import android.provider.MediaStore; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.LinearLayout; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.core.app.SharedElementCallback; -import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.snackbar.Snackbar; import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; import java.io.File; import java.io.IOException; import java.time.Instant; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -41,8 +46,8 @@ import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.WrappedLiv import it.niedermann.nextcloud.deck.ui.branding.BrandedFragment; import it.niedermann.nextcloud.deck.ui.branding.BrandedSnackbar; import it.niedermann.nextcloud.deck.ui.card.EditCardViewModel; -import it.niedermann.nextcloud.deck.ui.card.attachments.picker.CardAttachmentPicker; import it.niedermann.nextcloud.deck.ui.card.attachments.picker.CardAttachmentPickerListener; +import it.niedermann.nextcloud.deck.ui.card.attachments.picker.GalleryAdapter; import it.niedermann.nextcloud.deck.ui.exception.ExceptionDialogFragment; import it.niedermann.nextcloud.deck.ui.takephoto.TakePhotoActivity; import it.niedermann.nextcloud.deck.util.VCardUtil; @@ -58,6 +63,9 @@ import static android.view.View.GONE; import static android.view.View.VISIBLE; import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED; import static androidx.core.content.PermissionChecker.checkSelfPermission; +import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED; +import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HALF_EXPANDED; +import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN; import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce; import static it.niedermann.nextcloud.deck.ui.branding.BrandingUtil.applyBrandToFAB; import static it.niedermann.nextcloud.deck.ui.card.attachments.CardAttachmentAdapter.VIEW_TYPE_DEFAULT; @@ -69,6 +77,7 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme private FragmentCardEditTabAttachmentsBinding binding; private EditCardViewModel viewModel; + private BottomSheetBehavior<LinearLayout> mBottomSheetBehaviour; private static final int REQUEST_CODE_ADD_FILE = 1; private static final int REQUEST_CODE_ADD_FILE_PERMISSION = 2; @@ -79,8 +88,6 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme private SyncManager syncManager; private CardAttachmentAdapter adapter; - @Nullable - private DialogFragment picker; private int clickedItemPosition; @@ -118,6 +125,46 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme } }); + mBottomSheetBehaviour = BottomSheetBehavior.from(binding.bottomSheetParent); + mBottomSheetBehaviour.setDraggable(true); + mBottomSheetBehaviour.setHideable(true); + mBottomSheetBehaviour.setState(STATE_HIDDEN); + mBottomSheetBehaviour.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { + @Override + public void onStateChanged(@NonNull View bottomSheet, int newState) { + switch (newState) { + case STATE_HIDDEN: { + binding.bottomNavigation.setVisibility(GONE); + break; + } + case STATE_EXPANDED: + case STATE_HALF_EXPANDED: { + binding.bottomNavigation.setVisibility(VISIBLE); + break; + } + } + } + + @Override + public void onSlide(@NonNull View bottomSheet, float slideOffset) { + + } + }); + GalleryAdapter galleryAdapter = new GalleryAdapter(); + List<Long> imageIds = Collections.emptyList(); + if (SDK_INT >= LOLLIPOP) { + final ContentResolver contentResolver = requireContext().getContentResolver(); + try (final Cursor outerCursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null)) { + imageIds = new ArrayList<>(outerCursor.getCount()); + while (outerCursor.moveToNext()) { + imageIds.add(outerCursor.getLong(outerCursor.getColumnIndex(MediaStore.Images.Media._ID))); + } + } + } + binding.pickerRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3)); + galleryAdapter.setImageIds(imageIds); + binding.pickerRecyclerView.setAdapter(galleryAdapter); + final DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); int spanCount = (int) ((displayMetrics.widthPixels / displayMetrics.density) / getResources().getInteger(R.integer.max_dp_attachment_column)); GridLayoutManager glm = new GridLayoutManager(getContext(), spanCount); @@ -152,8 +199,10 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme if (viewModel.canEdit()) { binding.fab.setOnClickListener(v -> { - picker = CardAttachmentPicker.newInstance(); - picker.show(getChildFragmentManager(), CardAttachmentPicker.class.getSimpleName()); +// picker = CardAttachmentPicker.newInstance(); +// picker.show(getChildFragmentManager(), CardAttachmentPicker.class.getSimpleName()); + mBottomSheetBehaviour.setState(STATE_HALF_EXPANDED); + binding.bottomNavigation.setVisibility(VISIBLE); }); binding.fab.show(); binding.attachmentsList.addOnScrollListener(new RecyclerView.OnScrollListener() { @@ -231,9 +280,7 @@ public class CardAttachmentsFragment extends BrandedFragment implements Attachme uploadNewAttachmentFromUri(sourceUri, requestCode == REQUEST_CODE_CAMERA ? data.getType() : requireContext().getContentResolver().getType(sourceUri)); - if (picker != null) { - picker.dismiss(); - } + mBottomSheetBehaviour.setState(STATE_HIDDEN); } catch (Exception e) { ExceptionDialogFragment.newInstance(e, viewModel.getAccount()).show(getChildFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/CardAttachmentPicker.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/CardAttachmentPicker.java index 33063d1c7..7b22250ce 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/CardAttachmentPicker.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/CardAttachmentPicker.java @@ -16,7 +16,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -39,7 +38,6 @@ import it.niedermann.nextcloud.deck.util.DeckColorUtil; import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION_CODES.LOLLIPOP; -import static android.view.View.GONE; import static it.niedermann.nextcloud.deck.ui.branding.BrandingUtil.isBrandingEnabled; import static it.niedermann.nextcloud.deck.ui.branding.BrandingUtil.readBrandMainColor; @@ -48,7 +46,7 @@ public class CardAttachmentPicker extends BottomSheetDialogFragment implements B private DialogAttachmentPickerBinding binding; private CardAttachmentPickerListener listener; - private ImageView[] brandedViews; + private ImageView[] brandedViews = new ImageView[0]; public CardAttachmentPicker() { @@ -69,11 +67,11 @@ public class CardAttachmentPicker extends BottomSheetDialogFragment implements B @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = DialogAttachmentPickerBinding.inflate(inflater, container, false); - brandedViews = new ImageView[]{binding.pickCameraIamge, binding.pickContactIamge, binding.pickFileIamge}; +// brandedViews = new ImageView[]{binding.pickCameraIamge, binding.pickContactIamge, binding.pickFileIamge}; - if (SDK_INT < LOLLIPOP) { - binding.pickCamera.setVisibility(GONE); - } +// if (SDK_INT < LOLLIPOP) { +// binding.pickCamera.setVisibility(GONE); +// } @Nullable Context context = getContext(); if (context != null) { @@ -95,15 +93,15 @@ public class CardAttachmentPicker extends BottomSheetDialogFragment implements B @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - binding.pickCamera.setOnClickListener((v) -> { - if (SDK_INT >= LOLLIPOP) { - listener.pickCamera(); - } else { - Toast.makeText(requireContext(), R.string.min_api_21, Toast.LENGTH_SHORT).show(); - } - }); - binding.pickContact.setOnClickListener((v) -> listener.pickContact()); - binding.pickFile.setOnClickListener((v) -> listener.pickFile()); +// binding.pickCamera.setOnClickListener((v) -> { +// if (SDK_INT >= LOLLIPOP) { +// listener.pickCamera(); +// } else { +// Toast.makeText(requireContext(), R.string.min_api_21, Toast.LENGTH_SHORT).show(); +// } +// }); +// binding.pickContact.setOnClickListener((v) -> listener.pickContact()); +// binding.pickFile.setOnClickListener((v) -> listener.pickFile()); loadAndDisplayContacts(); loadAndDisplayGallery(); 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 new file mode 100644 index 000000000..faad73e8a --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryAdapter.java @@ -0,0 +1,50 @@ +package it.niedermann.nextcloud.deck.ui.card.attachments.picker; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import it.niedermann.nextcloud.deck.databinding.ItemAttachmentImageBinding; + +public class GalleryAdapter extends RecyclerView.Adapter<GalleryItemViewHolder> { + + @NonNull + List<Long> imageIds = new ArrayList<>(); + + public GalleryAdapter() { + setHasStableIds(true); + } + + public void setImageIds(@NonNull Collection<Long> imageIds) { + this.imageIds.clear(); + this.imageIds.addAll(imageIds); + notifyDataSetChanged(); + } + + @Override + public long getItemId(int position) { + return super.getItemId(position); + } + + @NonNull + @Override + public GalleryItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new GalleryItemViewHolder(ItemAttachmentImageBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull GalleryItemViewHolder holder, int position) { + holder.bind(imageIds.get(position)); + } + + @Override + public int getItemCount() { + return this.imageIds.size(); + } +} 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 new file mode 100644 index 000000000..7a409c748 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/picker/GalleryItemViewHolder.java @@ -0,0 +1,30 @@ +package it.niedermann.nextcloud.deck.ui.card.attachments.picker; + +import android.content.Context; +import android.provider.MediaStore; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; + +import it.niedermann.nextcloud.deck.databinding.ItemAttachmentImageBinding; + +public class GalleryItemViewHolder extends RecyclerView.ViewHolder { + + ItemAttachmentImageBinding binding; + + public GalleryItemViewHolder(@NonNull ItemAttachmentImageBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + + public void bind(@NonNull Long imageId) { + Context context = itemView.getContext(); + Glide.with(context) + .load(MediaStore.Images.Thumbnails.getThumbnail( + context.getContentResolver(), imageId, + MediaStore.Images.Thumbnails.MINI_KIND, null)) + .into(binding.preview); + } +} |