Swipe to see gallery images in PostDetailRecyclerViewAdapter.

This commit is contained in:
Docile-Alligator 2022-11-14 18:44:07 +11:00
parent a95c77731a
commit af870c157b
5 changed files with 288 additions and 227 deletions

View File

@ -15,10 +15,12 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
@ -31,6 +33,7 @@ import androidx.appcompat.content.res.AppCompatResources;
import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet; import androidx.constraintlayout.widget.ConstraintSet;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.RequestBuilder;
@ -130,7 +133,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
private RedditDataRoomDatabase mRedditDataRoomDatabase; private RedditDataRoomDatabase mRedditDataRoomDatabase;
private SharedPreferences mCurrentAccountSharedPreferences; private SharedPreferences mCurrentAccountSharedPreferences;
private RequestManager mGlide; private RequestManager mGlide;
private SaveMemoryCenterInisdeDownsampleStrategy mSaveMemoryCenterInsideDownSampleStrategy; private SaveMemoryCenterInisdeDownsampleStrategy mSaveMemoryCenterInsideDownsampleStrategy;
private Markwon mPostDetailMarkwon; private Markwon mPostDetailMarkwon;
private final MarkwonAdapter mMarkwonAdapter; private final MarkwonAdapter mMarkwonAdapter;
private String mAccessToken; private String mAccessToken;
@ -225,7 +228,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
mStreamableRetrofit = streamableRetrofit; mStreamableRetrofit = streamableRetrofit;
mRedditDataRoomDatabase = redditDataRoomDatabase; mRedditDataRoomDatabase = redditDataRoomDatabase;
mGlide = glide; mGlide = glide;
mSaveMemoryCenterInsideDownSampleStrategy = new SaveMemoryCenterInisdeDownsampleStrategy(Integer.parseInt(sharedPreferences.getString(SharedPreferencesUtils.POST_FEED_MAX_RESOLUTION, "5000000"))); mSaveMemoryCenterInsideDownsampleStrategy = new SaveMemoryCenterInisdeDownsampleStrategy(Integer.parseInt(sharedPreferences.getString(SharedPreferencesUtils.POST_FEED_MAX_RESOLUTION, "5000000")));
mCurrentAccountSharedPreferences = currentAccountSharedPreferences; mCurrentAccountSharedPreferences = currentAccountSharedPreferences;
mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor();
int markdownColor = customThemeWrapper.getPostContentColor(); int markdownColor = customThemeWrapper.getPostContentColor();
@ -637,7 +640,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
Post.Preview preview = getSuitablePreview(mPost.getPreviews()); Post.Preview preview = getSuitablePreview(mPost.getPreviews());
if (preview != null) { if (preview != null) {
((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight());
mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownSampleStrategy).into(((PostDetailVideoAutoplayViewHolder) holder).previewImageView); mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostDetailVideoAutoplayViewHolder) holder).previewImageView);
} else { } else {
((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1);
} }
@ -767,42 +770,27 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
} }
} }
} else if (holder instanceof PostDetailGalleryViewHolder) { } else if (holder instanceof PostDetailGalleryViewHolder) {
if (mDataSavingMode && mDisableImagePreview) {
((PostDetailGalleryViewHolder) holder).mNoPreviewPostTypeImageView.setVisibility(View.VISIBLE);
((PostDetailGalleryViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_gallery_24dp);
} else {
((PostDetailGalleryViewHolder) holder).galleryFrameLayout.setVisibility(View.VISIBLE);
((PostDetailGalleryViewHolder) holder).imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, 1, mPost.getGallery().size()));
Post.Preview preview = getSuitablePreview(mPost.getPreviews()); Post.Preview preview = getSuitablePreview(mPost.getPreviews());
if (preview != null) { if (preview != null) {
((PostDetailGalleryViewHolder) holder).mRelativeLayout.setVisibility(View.VISIBLE); if (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0) {
((PostDetailGalleryViewHolder) holder).mImageView ((PostDetailGalleryViewHolder) holder).adapter.setRatio(-1);
.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth());
loadImage((PostDetailGalleryViewHolder) holder, preview);
loadCaptionPreview((PostDetailGalleryViewHolder) holder, preview);
} else { } else {
((PostDetailGalleryViewHolder) holder).mNoPreviewPostTypeImageView.setVisibility(View.VISIBLE); ((PostDetailGalleryViewHolder) holder).adapter.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth());
} }
} else {
((PostDetailGalleryViewHolder) holder).adapter.setRatio(-1);
} }
((PostDetailGalleryViewHolder) holder).adapter.setGalleryImages(mPost.getGallery());
((PostDetailGalleryViewHolder) holder).adapter.setBlurImage(
(mPost.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit())) || (mPost.isSpoiler() && mNeedBlurSpoiler));
} }
} }
private void loadCaptionPreview(PostDetailBaseViewHolder holder, Post.Preview preview) {
if (holder instanceof PostDetailGalleryViewHolder) {
String previewCaption = preview.getPreviewCaption();
String previewCaptionUrl = preview.getPreviewCaptionUrl();
boolean previewCaptionIsEmpty = TextUtils.isEmpty(previewCaption);
boolean previewCaptionUrlIsEmpty = TextUtils.isEmpty(previewCaptionUrl);
if (!previewCaptionIsEmpty || !previewCaptionUrlIsEmpty) {
((PostDetailGalleryViewHolder) holder).mCaptionConstraintLayout.setBackgroundColor(mCardViewColor & 0x0D000000); // Make 10% darker than CardViewColor
((PostDetailGalleryViewHolder) holder).mCaptionConstraintLayout.setVisibility(View.VISIBLE);
}
if (!previewCaptionIsEmpty) {
((PostDetailGalleryViewHolder) holder).mCaptionTextView.setTextColor(mCommentColor);
((PostDetailGalleryViewHolder) holder).mCaptionTextView.setText(previewCaption);
((PostDetailGalleryViewHolder) holder).mCaptionTextView.setSelected(true);
}
if (!previewCaptionUrlIsEmpty) {
String domain = Uri.parse(previewCaptionUrl).getHost();
domain = domain.startsWith("www.") ? domain.substring(4) : domain;
mPostDetailMarkwon.setMarkdown(((PostDetailGalleryViewHolder) holder).mCaptionUrlTextView, String.format("[%s](%s)", domain, previewCaptionUrl));
}
} }
} }
@ -860,7 +848,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
if (blurImage) { if (blurImage) {
imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView);
} else { } else {
imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownSampleStrategy).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView);
} }
} else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) {
RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(preview.getPreviewUrl())
@ -888,7 +876,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10)))
.into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); .into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView);
} else { } else {
imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownSampleStrategy).into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView);
} }
} else if (holder instanceof PostDetailLinkViewHolder) { } else if (holder instanceof PostDetailLinkViewHolder) {
RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(preview.getPreviewUrl())
@ -916,34 +904,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10)))
.into(((PostDetailLinkViewHolder) holder).mImageView); .into(((PostDetailLinkViewHolder) holder).mImageView);
} else { } else {
imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownSampleStrategy).into(((PostDetailLinkViewHolder) holder).mImageView); imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostDetailLinkViewHolder) holder).mImageView);
}
} else if (holder instanceof PostDetailGalleryViewHolder) {
RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(preview.getPreviewUrl())
.listener(new RequestListener<>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
((PostDetailGalleryViewHolder) holder).mLoadImageProgressBar.setVisibility(View.GONE);
((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.VISIBLE);
((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setOnClickListener(view -> {
((PostDetailGalleryViewHolder) holder).mLoadImageProgressBar.setVisibility(View.VISIBLE);
((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.GONE);
loadImage(holder, preview);
});
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
((PostDetailGalleryViewHolder) holder).mLoadWrapper.setVisibility(View.GONE);
return false;
}
});
if ((mPost.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(mPost.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || (mPost.isSpoiler() && mNeedBlurSpoiler)) {
imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailGalleryViewHolder) holder).mImageView);
} else {
imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownSampleStrategy).into(((PostDetailGalleryViewHolder) holder).mImageView);
} }
} }
} }
@ -1030,6 +991,9 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
mGlide.clear(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); mGlide.clear(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView);
} else if (holder instanceof PostDetailLinkViewHolder) { } else if (holder instanceof PostDetailLinkViewHolder) {
mGlide.clear(((PostDetailLinkViewHolder) holder).mImageView); mGlide.clear(((PostDetailLinkViewHolder) holder).mImageView);
} else if (holder instanceof PostDetailGalleryViewHolder) {
((PostDetailGalleryViewHolder) holder).galleryFrameLayout.setVisibility(View.GONE);
((PostDetailGalleryViewHolder) holder).mNoPreviewPostTypeImageView.setVisibility(View.GONE);
} }
} }
} }
@ -2308,24 +2272,12 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
TextView mAwardsTextView; TextView mAwardsTextView;
@BindView(R.id.upvote_ratio_text_view_item_post_detail_gallery) @BindView(R.id.upvote_ratio_text_view_item_post_detail_gallery)
TextView mUpvoteRatioTextView; TextView mUpvoteRatioTextView;
@BindView(R.id.image_view_wrapper_item_post_detail_gallery) @BindView(R.id.gallery_frame_layout_item_post_detail_gallery)
RelativeLayout mRelativeLayout; FrameLayout galleryFrameLayout;
@BindView(R.id.load_wrapper_item_post_detail_gallery) @BindView(R.id.gallery_recycler_view_item_post_detail_gallery)
RelativeLayout mLoadWrapper; RecyclerView galleryRecyclerView;
@BindView(R.id.progress_bar_item_post_detail_gallery) @BindView(R.id.image_index_text_view_item_post_detail_gallery)
ProgressBar mLoadImageProgressBar; CustomTextView imageIndexTextView;
@BindView(R.id.load_image_error_text_view_item_post_detail_gallery)
TextView mLoadImageErrorTextView;
@BindView(R.id.video_or_gif_indicator_image_view_item_post_detail)
ImageView videoOrGifIndicatorImageView;
@BindView(R.id.image_view_item_post_detail_gallery)
AspectRatioGifImageView mImageView;
@BindView(R.id.caption_constraint_layout_item_post_detail_gallery)
ConstraintLayout mCaptionConstraintLayout;
@BindView(R.id.caption_text_view_item_post_detail_gallery)
TextView mCaptionTextView;
@BindView(R.id.caption_url_text_view_item_post_detail_gallery)
TextView mCaptionUrlTextView;
@BindView(R.id.image_view_no_preview_link_item_post_detail_gallery) @BindView(R.id.image_view_no_preview_link_item_post_detail_gallery)
ImageView mNoPreviewPostTypeImageView; ImageView mNoPreviewPostTypeImageView;
@BindView(R.id.content_markdown_view_item_post_detail_gallery) @BindView(R.id.content_markdown_view_item_post_detail_gallery)
@ -2344,6 +2296,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
ImageView mSaveButton; ImageView mSaveButton;
@BindView(R.id.share_button_item_post_detail_gallery) @BindView(R.id.share_button_item_post_detail_gallery)
ImageView mShareButton; ImageView mShareButton;
PostGalleryTypeImageRecyclerViewAdapter adapter;
PostDetailGalleryViewHolder(@NonNull View itemView) { PostDetailGalleryViewHolder(@NonNull View itemView) {
super(itemView); super(itemView);
@ -2373,26 +2326,102 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
mShareButton); mShareButton);
if (mActivity.typeface != null) { if (mActivity.typeface != null) {
mLoadImageErrorTextView.setTypeface(mActivity.typeface); imageIndexTextView.setTypeface(mActivity.typeface);
mCaptionTextView.setTypeface(mActivity.typeface);
mCaptionUrlTextView.setTypeface(mActivity.typeface);
} }
videoOrGifIndicatorImageView.setColorFilter(mMediaIndicatorIconTint, PorterDuff.Mode.SRC_IN);
videoOrGifIndicatorImageView.setBackgroundTintList(ColorStateList.valueOf(mMediaIndicatorBackgroundColor)); imageIndexTextView.setTextColor(mMediaIndicatorIconTint);
mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); imageIndexTextView.setBackgroundColor(mMediaIndicatorBackgroundColor);
mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); imageIndexTextView.setBorderColor(mMediaIndicatorBackgroundColor);
mNoPreviewPostTypeImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); mNoPreviewPostTypeImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor);
mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, PorterDuff.Mode.SRC_IN); mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, PorterDuff.Mode.SRC_IN);
mImageView.setOnClickListener(view -> { adapter = new PostGalleryTypeImageRecyclerViewAdapter(mGlide, mActivity.typeface, mPostDetailMarkwon,
mSaveMemoryCenterInsideDownsampleStrategy, mColorAccent, mPrimaryTextColor,
mCardViewColor, mCommentColor, mScale);
galleryRecyclerView.setAdapter(adapter);
new PagerSnapHelper().attachToRecyclerView(galleryRecyclerView);
SwipeLockLinearLayoutManager layoutManager = new SwipeLockLinearLayoutManager(
mActivity, RecyclerView.HORIZONTAL, false, new SwipeLockInterface() {
@Override
public void lockSwipe() {
mActivity.lockSwipeRightToGoBack();
}
@Override
public void unlockSwipe() {
mActivity.unlockSwipeRightToGoBack();
}
});
galleryRecyclerView.setLayoutManager(layoutManager);
galleryRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, layoutManager.findFirstVisibleItemPosition() + 1, mPost.getGallery().size()));
}
});
galleryRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
private float downX;
private float downY;
private boolean dragged;
private final int minTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
@Override
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
int action = e.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downX = e.getRawX();
downY = e.getRawY();
break;
case MotionEvent.ACTION_MOVE:
if(Math.abs(e.getRawX() - downX) > minTouchSlop || Math.abs(e.getRawY() - downY) > minTouchSlop) {
dragged = true;
}
break;
case MotionEvent.ACTION_UP:
if (!dragged) {
int position = getBindingAdapterPosition();
if (position >= 0) {
if (mPost != null) {
Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class); Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class);
intent.putParcelableArrayListExtra(ViewRedditGalleryActivity.EXTRA_REDDIT_GALLERY, mPost.getGallery()); intent.putParcelableArrayListExtra(ViewRedditGalleryActivity.EXTRA_REDDIT_GALLERY, mPost.getGallery());
intent.putExtra(ViewRedditGalleryActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); intent.putExtra(ViewRedditGalleryActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName());
intent.putExtra(ViewRedditGalleryActivity.EXTRA_GALLERY_ITEM_INDEX, layoutManager.findFirstVisibleItemPosition());
mActivity.startActivity(intent); mActivity.startActivity(intent);
}
}
}
downX = 0;
downY = 0;
dragged = false;
}
return false;
}
@Override
public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}); });
mNoPreviewPostTypeImageView.setOnClickListener(view -> { mNoPreviewPostTypeImageView.setOnClickListener(view -> {
mImageView.performClick(); Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class);
intent.putParcelableArrayListExtra(ViewRedditGalleryActivity.EXTRA_REDDIT_GALLERY, mPost.getGallery());
intent.putExtra(ViewRedditGalleryActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName());
intent.putExtra(ViewRedditGalleryActivity.EXTRA_GALLERY_ITEM_INDEX, layoutManager.findFirstVisibleItemPosition());
mActivity.startActivity(intent);
}); });
} }
} }

View File

@ -3,6 +3,8 @@ package ml.docilealligator.infinityforreddit.adapters;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -22,6 +24,7 @@ import com.bumptech.glide.request.target.Target;
import java.util.ArrayList; import java.util.ArrayList;
import io.noties.markwon.Markwon;
import jp.wasabeef.glide.transformations.BlurTransformation; import jp.wasabeef.glide.transformations.BlurTransformation;
import ml.docilealligator.infinityforreddit.SaveMemoryCenterInisdeDownsampleStrategy; import ml.docilealligator.infinityforreddit.SaveMemoryCenterInisdeDownsampleStrategy;
import ml.docilealligator.infinityforreddit.databinding.ItemGalleryImageInPostFeedBinding; import ml.docilealligator.infinityforreddit.databinding.ItemGalleryImageInPostFeedBinding;
@ -30,13 +33,17 @@ import ml.docilealligator.infinityforreddit.post.Post;
public class PostGalleryTypeImageRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class PostGalleryTypeImageRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private RequestManager glide; private RequestManager glide;
private Typeface typeface; private Typeface typeface;
private Markwon mPostDetailMarkwon;
private SaveMemoryCenterInisdeDownsampleStrategy saveMemoryCenterInisdeDownsampleStrategy; private SaveMemoryCenterInisdeDownsampleStrategy saveMemoryCenterInisdeDownsampleStrategy;
private int mColorAccent; private int mColorAccent;
private int mPrimaryTextColor; private int mPrimaryTextColor;
private int mCardViewColor;
private int mCommentColor;
private float mScale; private float mScale;
private ArrayList<Post.Gallery> galleryImages; private ArrayList<Post.Gallery> galleryImages;
private boolean blurImage; private boolean blurImage;
private float ratio; private float ratio;
private boolean showCaption;
public PostGalleryTypeImageRecyclerViewAdapter(RequestManager glide, Typeface typeface, public PostGalleryTypeImageRecyclerViewAdapter(RequestManager glide, Typeface typeface,
SaveMemoryCenterInisdeDownsampleStrategy saveMemoryCenterInisdeDownsampleStrategy, SaveMemoryCenterInisdeDownsampleStrategy saveMemoryCenterInisdeDownsampleStrategy,
@ -47,6 +54,23 @@ public class PostGalleryTypeImageRecyclerViewAdapter extends RecyclerView.Adapte
this.mColorAccent = mColorAccent; this.mColorAccent = mColorAccent;
this.mPrimaryTextColor = mPrimaryTextColor; this.mPrimaryTextColor = mPrimaryTextColor;
this.mScale = scale; this.mScale = scale;
showCaption = false;
}
public PostGalleryTypeImageRecyclerViewAdapter(RequestManager glide, Typeface typeface, Markwon postDetailMarkwon,
SaveMemoryCenterInisdeDownsampleStrategy saveMemoryCenterInisdeDownsampleStrategy,
int mColorAccent, int mPrimaryTextColor, int mCardViewColor,
int mCommentColor, float scale) {
this.glide = glide;
this.typeface = typeface;
this.mPostDetailMarkwon = postDetailMarkwon;
this.saveMemoryCenterInisdeDownsampleStrategy = saveMemoryCenterInisdeDownsampleStrategy;
this.mColorAccent = mColorAccent;
this.mPrimaryTextColor = mPrimaryTextColor;
this.mCardViewColor = mCardViewColor;
this.mCommentColor = mCommentColor;
this.mScale = scale;
showCaption = true;
} }
@NonNull @NonNull
@ -78,6 +102,10 @@ public class PostGalleryTypeImageRecyclerViewAdapter extends RecyclerView.Adapte
} }
}); });
if (showCaption) {
loadCaptionPreview((ImageViewHolder) holder);
}
loadImage((ImageViewHolder) holder); loadImage((ImageViewHolder) holder);
} }
} }
@ -90,6 +118,11 @@ public class PostGalleryTypeImageRecyclerViewAdapter extends RecyclerView.Adapte
@Override @Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
super.onViewRecycled(holder); super.onViewRecycled(holder);
if (holder instanceof ImageViewHolder) {
((ImageViewHolder) holder).binding.captionConstraintLayoutItemGalleryImageInPostFeed.setVisibility(View.GONE);
((ImageViewHolder) holder).binding.captionTextViewItemGalleryImageInPostFeed.setText("");
((ImageViewHolder) holder).binding.captionUrlTextViewItemGalleryImageInPostFeed.setText("");
}
} }
private void loadImage(ImageViewHolder holder) { private void loadImage(ImageViewHolder holder) {
@ -116,6 +149,27 @@ public class PostGalleryTypeImageRecyclerViewAdapter extends RecyclerView.Adapte
} }
} }
private void loadCaptionPreview(ImageViewHolder holder) {
String previewCaption = galleryImages.get(holder.getBindingAdapterPosition()).caption;
String previewCaptionUrl = galleryImages.get(holder.getBindingAdapterPosition()).captionUrl;
boolean previewCaptionIsEmpty = TextUtils.isEmpty(previewCaption);
boolean previewCaptionUrlIsEmpty = TextUtils.isEmpty(previewCaptionUrl);
if (!previewCaptionIsEmpty || !previewCaptionUrlIsEmpty) {
holder.binding.captionConstraintLayoutItemGalleryImageInPostFeed.setBackgroundColor(mCardViewColor & 0x0D000000); // Make 10% darker than CardViewColor
holder.binding.captionConstraintLayoutItemGalleryImageInPostFeed.setVisibility(View.VISIBLE);
}
if (!previewCaptionIsEmpty) {
holder.binding.captionTextViewItemGalleryImageInPostFeed.setTextColor(mCommentColor);
holder.binding.captionTextViewItemGalleryImageInPostFeed.setText(previewCaption);
holder.binding.captionTextViewItemGalleryImageInPostFeed.setSelected(true);
}
if (!previewCaptionUrlIsEmpty) {
String domain = Uri.parse(previewCaptionUrl).getHost();
domain = domain.startsWith("www.") ? domain.substring(4) : domain;
mPostDetailMarkwon.setMarkdown(holder.binding.captionUrlTextViewItemGalleryImageInPostFeed, String.format("[%s](%s)", domain, previewCaptionUrl));
}
}
public void setGalleryImages(ArrayList<Post.Gallery> galleryImages) { public void setGalleryImages(ArrayList<Post.Gallery> galleryImages) {
this.galleryImages = galleryImages; this.galleryImages = galleryImages;
notifyDataSetChanged(); notifyDataSetChanged();

View File

@ -4,29 +4,29 @@ import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.widget.FrameLayout; import android.widget.LinearLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
public class SwipeLockFrameLayout extends FrameLayout implements SwipeLockView { public class SwipeLockLinearLayout extends LinearLayout implements SwipeLockView {
@Nullable @Nullable
private SwipeLockInterface swipeLockInterface = null; private SwipeLockInterface swipeLockInterface = null;
private boolean locked = false; private boolean locked = false;
public SwipeLockFrameLayout(@NonNull Context context) { public SwipeLockLinearLayout(@NonNull Context context) {
super(context); super(context);
} }
public SwipeLockFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) { public SwipeLockLinearLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs); super(context, attrs);
} }
public SwipeLockFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { public SwipeLockLinearLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
} }
public SwipeLockFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { public SwipeLockLinearLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes); super(context, attrs, defStyleAttr, defStyleRes);
} }

View File

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ml.docilealligator.infinityforreddit.customviews.SwipeLockFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <ml.docilealligator.infinityforreddit.customviews.SwipeLockLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@ -27,4 +33,60 @@
android:fontFamily="?attr/font_family" android:fontFamily="?attr/font_family"
android:visibility="gone" /> android:visibility="gone" />
</ml.docilealligator.infinityforreddit.customviews.SwipeLockFrameLayout> </FrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/caption_constraint_layout_item_gallery_image_in_post_feed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorBackgroundFloating"
android:visibility="gone">
<TextView
android:id="@+id/caption_text_view_item_gallery_image_in_post_feed"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:fontFamily="?attr/content_font_family"
android:gravity="start"
android:marqueeRepeatLimit="marquee_forever"
android:paddingHorizontal="8dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="?attr/content_font_default"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/caption_url_text_view_item_gallery_image_in_post_feed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/caption_url_text_view_item_gallery_image_in_post_feed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="?attr/content_font_family"
android:gravity="end"
android:maxLines="1"
android:paddingHorizontal="8dp"
android:textColor="?attr/primaryTextColor"
android:textSize="?attr/content_font_default"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintLeft_toRightOf="@id/guideline4"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline4"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.50" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ml.docilealligator.infinityforreddit.customviews.SwipeLockLinearLayout>

View File

@ -202,61 +202,31 @@
</com.nex3z.flowlayout.FlowLayout> </com.nex3z.flowlayout.FlowLayout>
<RelativeLayout <FrameLayout
android:id="@+id/image_view_wrapper_item_post_detail_gallery" android:id="@+id/gallery_frame_layout_item_post_detail_gallery"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone"> android:visibility="gone">
<FrameLayout <androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent" android:id="@+id/gallery_recycler_view_item_post_detail_gallery"
android:layout_height="wrap_content">
<ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView
android:id="@+id/image_view_item_post_detail_gallery"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:adjustViewBounds="true" /> android:orientation="horizontal" />
<ImageView <com.libRG.CustomTextView
android:id="@+id/video_or_gif_indicator_image_view_item_post_detail" android:id="@+id/image_index_text_view_item_post_detail_gallery"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_margin="16dp"
android:layout_gravity="start"
android:scaleType="center"
android:background="@drawable/play_button_round_background"
android:src="@drawable/ic_gallery_24dp" />
</FrameLayout>
<RelativeLayout
android:id="@+id/load_wrapper_item_post_detail_gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<ProgressBar
android:id="@+id/progress_bar_item_post_detail_gallery"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" /> android:layout_margin="16dp"
android:textSize="?attr/font_12"
<TextView
android:id="@+id/load_image_error_text_view_item_post_detail_gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_error_outline_black_24dp"
android:layout_centerInParent="true"
android:gravity="center"
android:text="@string/error_loading_image_tap_to_retry"
android:textSize="?attr/font_default"
android:fontFamily="?attr/font_family" android:fontFamily="?attr/font_family"
android:visibility="gone" /> android:padding="4dp"
app:lib_setRadius="6dp"
app:lib_setRoundedView="true"
app:lib_setShape="rectangle" />
</RelativeLayout> </FrameLayout>
</RelativeLayout>
<ImageView <ImageView
android:id="@+id/image_view_no_preview_link_item_post_detail_gallery" android:id="@+id/image_view_no_preview_link_item_post_detail_gallery"
@ -266,60 +236,6 @@
android:src="@drawable/ic_link" android:src="@drawable/ic_link"
android:visibility="gone" /> android:visibility="gone" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/caption_constraint_layout_item_post_detail_gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorBackgroundFloating"
android:visibility="gone">
<TextView
android:id="@+id/caption_text_view_item_post_detail_gallery"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:fontFamily="?attr/content_font_family"
android:gravity="start"
android:marqueeRepeatLimit="marquee_forever"
android:paddingHorizontal="8dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="?attr/content_font_default"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/caption_url_text_view_item_post_detail_gallery"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/caption_url_text_view_item_post_detail_gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="?attr/content_font_family"
android:gravity="end"
android:maxLines="1"
android:paddingHorizontal="8dp"
android:textColor="?attr/primaryTextColor"
android:textSize="?attr/content_font_default"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintLeft_toRightOf="@id/guideline4"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline4"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.50" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/content_markdown_view_item_post_detail_gallery" android:id="@+id/content_markdown_view_item_post_detail_gallery"
android:layout_width="match_parent" android:layout_width="match_parent"