Use AspectRatiotImageView instead of ImageView to fully display the preview images of posts and prevent scrolling jump in PostFragment and ViewPostDetailActivity.

This commit is contained in:
Alex Ning 2018-10-28 23:18:01 +08:00
parent 66402e661b
commit 6e5a0e7ef3
10 changed files with 102 additions and 29 deletions

View File

@ -64,4 +64,5 @@ dependencies {
annotationProcessor 'com.google.dagger:dagger-compiler:2.17'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.github.santalu:aspect-ratio-imageview:1.0.6'
}

View File

@ -82,19 +82,27 @@ class ParsePost {
String permalink = data.getString(JSONUtils.PERMALINK_KEY);
String previewUrl = "";
int previewWidth = -1;
int previewHeight = -1;
if(data.has(JSONUtils.PREVIEW_KEY)) {
previewUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0)
.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY);
previewWidth = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0)
.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY);
previewHeight = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0)
.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY);
}
if(data.has(JSONUtils.CROSSPOST_PARENT_LIST)) {
//Cross post
data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0);
parseData(data, permalink, newPostData, id, fullName, subredditNamePrefixed,
formattedPostTime, title, previewUrl, score, voteType, gilded, nsfw, stickied, true, i);
formattedPostTime, title, previewUrl, previewWidth, previewHeight,
score, voteType, gilded, nsfw, stickied, true, i);
} else {
parseData(data, permalink, newPostData, id, fullName, subredditNamePrefixed,
formattedPostTime, title, previewUrl, score, voteType, gilded, nsfw, stickied, false, i);
formattedPostTime, title, previewUrl, previewWidth, previewHeight,
score, voteType, gilded, nsfw, stickied, false, i);
}
}
} catch (JSONException e) {
@ -117,7 +125,7 @@ class ParsePost {
private static void parseData(JSONObject data, String permalink, ArrayList<PostData> bestPostData,
String id, String fullName, String subredditNamePrefixed, String formattedPostTime,
String title, String previewUrl, int score, int voteType, int gilded,
String title, String previewUrl, int previewWidth, int previewHeight ,int score, int voteType, int gilded,
boolean nsfw, boolean stickied, boolean isCrosspost, int i) throws JSONException {
boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY);
String url = data.getString(JSONUtils.URL_KEY);
@ -140,7 +148,8 @@ class ParsePost {
Log.i("no preview link", Integer.toString(i));
int postType = PostData.NO_PREVIEW_LINK_TYPE;
PostData linkPostData = new PostData(id, fullName, subredditNamePrefixed, formattedPostTime,
title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost);
title, previewUrl, url, permalink, score, postType,
voteType, gilded, nsfw, stickied, isCrosspost);
if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) {
linkPostData.setSelfText("");
} else {
@ -156,8 +165,11 @@ class ParsePost {
String videoUrl = redditVideoObject.getString(JSONUtils.DASH_URL_KEY);
PostData videoPostData = new PostData(id, fullName, subredditNamePrefixed, formattedPostTime,
title, previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost, true);
title, previewUrl, permalink, score, postType, voteType,
gilded, nsfw, stickied, isCrosspost, true);
videoPostData.setPreviewWidth(previewWidth);
videoPostData.setPreviewHeight(previewHeight);
videoPostData.setVideoUrl(videoUrl);
videoPostData.setDownloadableGifOrVideo(false);
@ -171,8 +183,11 @@ class ParsePost {
String videoUrl = variations.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.MP4_KEY).getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY);
String gifDownloadUrl = variations.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.GIF_KEY).getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY);
PostData post = new PostData(id, fullName, subredditNamePrefixed, formattedPostTime, title,
previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost, false);
previewUrl, permalink, score, postType, voteType,
gilded, nsfw, stickied, isCrosspost, false);
post.setPreviewWidth(previewWidth);
post.setPreviewHeight(previewHeight);
post.setVideoUrl(videoUrl);
post.setDownloadableGifOrVideo(true);
post.setGifOrVideoDownloadUrl(gifDownloadUrl);
@ -186,8 +201,11 @@ class ParsePost {
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.DASH_URL_KEY);
PostData post = new PostData(id, fullName, subredditNamePrefixed, formattedPostTime, title,
previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost, true);
previewUrl, permalink, score, postType, voteType,
gilded, nsfw, stickied, isCrosspost, true);
post.setPreviewWidth(previewWidth);
post.setPreviewHeight(previewHeight);
post.setVideoUrl(videoUrl);
post.setDownloadableGifOrVideo(false);
@ -197,8 +215,15 @@ class ParsePost {
//Image post
Log.i("image", Integer.toString(i));
int postType = PostData.IMAGE_TYPE;
bestPostData.add(new PostData(id, fullName, subredditNamePrefixed, formattedPostTime,
title, url, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost));
PostData imagePostData = new PostData(id, fullName, subredditNamePrefixed, formattedPostTime,
title, url, url, permalink, score, postType,
voteType, gilded, nsfw, stickied, isCrosspost);
imagePostData.setPreviewWidth(previewWidth);
imagePostData.setPreviewHeight(previewHeight);
bestPostData.add(imagePostData);
} else {
if (url.contains(permalink)) {
//Text post but with a preview
@ -206,6 +231,10 @@ class ParsePost {
int postType = PostData.TEXT_TYPE;
PostData textWithImagePostData = new PostData(id, fullName, subredditNamePrefixed, formattedPostTime,
title, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost);
textWithImagePostData.setPreviewWidth(previewWidth);
textWithImagePostData.setPreviewHeight(previewHeight);
if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) {
textWithImagePostData.setSelfText("");
} else {
@ -217,12 +246,17 @@ class ParsePost {
Log.i("link", Integer.toString(i));
int postType = PostData.LINK_TYPE;
PostData linkPostData = new PostData(id, fullName, subredditNamePrefixed, formattedPostTime,
title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost);
title, previewUrl, url, permalink, score,
postType, voteType, gilded, nsfw, stickied, isCrosspost);
if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) {
linkPostData.setSelfText("");
} else {
linkPostData.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim());
}
linkPostData.setPreviewWidth(previewWidth);
linkPostData.setPreviewHeight(previewHeight);
bestPostData.add(linkPostData);
}
}
@ -233,13 +267,15 @@ class ParsePost {
Log.i("CP no preview image", Integer.toString(i));
int postType = PostData.IMAGE_TYPE;
bestPostData.add(new PostData(id, fullName, subredditNamePrefixed, formattedPostTime, title,
url, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost));
url, url, permalink, score, postType, voteType,
gilded, nsfw, stickied, isCrosspost));
} else {
//Link post
Log.i("CP no preview link", Integer.toString(i));
int postType = PostData.LINK_TYPE;
PostData linkPostData = new PostData(id, fullName, subredditNamePrefixed, formattedPostTime,
title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost);
title, previewUrl, url, permalink, score, postType,
voteType, gilded, nsfw, stickied, isCrosspost);
bestPostData.add(linkPostData);
}
}

View File

@ -31,11 +31,14 @@ class PostData implements Parcelable {
private int postType;
private int voteType;
private int gilded;
private int previewWidth;
private int previewHeight;
private boolean nsfw;
private boolean stickied;
private boolean isCrosspost;
private boolean isDashVideo;
private boolean isDownloadableGifOrVideo;
private PostData crosspostParentPostData;
PostData(String id, String fullName, String subredditNamePrefixed, String postTime, String title,
String previewUrl, String permalink, int score, int postType, int voteType, int gilded,
@ -112,6 +115,8 @@ class PostData implements Parcelable {
postType = in.readInt();
voteType = in.readInt();
gilded = in.readInt();
previewWidth = in.readInt();
previewHeight = in.readInt();
nsfw = in.readByte() != 0;
stickied = in.readByte() != 0;
isCrosspost = in.readByte() != 0;
@ -223,6 +228,22 @@ class PostData implements Parcelable {
return gilded;
}
void setPreviewWidth(int previewWidth) {
this.previewWidth = previewWidth;
}
int getPreviewWidth() {
return previewWidth;
}
void setPreviewHeight(int previewHeight) {
this.previewHeight = previewHeight;
}
int getPreviewHeight() {
return previewHeight;
}
public boolean isNSFW() {
return nsfw;
}
@ -270,6 +291,8 @@ class PostData implements Parcelable {
parcel.writeInt(postType);
parcel.writeInt(voteType);
parcel.writeInt(gilded);
parcel.writeInt(previewWidth);
parcel.writeInt(previewHeight);
parcel.writeByte((byte) (nsfw ? 1 : 0));
parcel.writeByte((byte) (stickied ? 1 : 0));
parcel.writeByte((byte) (isCrosspost ? 1 : 0));

View File

@ -32,6 +32,7 @@ import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.santalu.aspectratioimageview.AspectRatioImageView;
import java.util.ArrayList;
@ -206,6 +207,8 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
((DataViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE);
((DataViewHolder) holder).progressBar.setVisibility(View.VISIBLE);
((DataViewHolder) holder).imageView.setVisibility(View.VISIBLE);
((DataViewHolder) holder).imageView
.setRatio((float) mPostData.get(position).getPreviewHeight() / mPostData.get(position).getPreviewWidth());
loadImage(holder, mPostData.get(holder.getAdapterPosition()));
}
@ -533,7 +536,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
@BindView(R.id.nsfw_text_view_item_best_post) TextView nsfwTextView;
@BindView(R.id.image_view_wrapper_item_best_post) RelativeLayout relativeLayout;
@BindView(R.id.progress_bar_best_post_item) ProgressBar progressBar;
@BindView(R.id.image_view_best_post_item) ImageView imageView;
@BindView(R.id.image_view_best_post_item) AspectRatioImageView imageView;
@BindView(R.id.load_image_error_linear_layout_best_post_item) LinearLayout errorLinearLayout;
@BindView(R.id.image_view_no_preview_link_best_post_item) ImageView noPreviewLinkImageView;
@BindView(R.id.plus_button_item_best_post) ImageView upvoteButton;

View File

@ -27,7 +27,7 @@ class SubscribedSubredditRecyclerViewAdapter extends RecyclerView.Adapter<Recycl
}
SubscribedSubredditRecyclerViewAdapter(Context context, OnItemClickListener onItemClickListener) {
mContext = context.getApplicationContext();
mContext = context;
glide = Glide.with(context.getApplicationContext());
mOnItemClickListener = onItemClickListener;
}

View File

@ -32,6 +32,7 @@ import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.multilevelview.MultiLevelRecyclerView;
import com.santalu.aspectratioimageview.AspectRatioImageView;
import org.sufficientlysecure.htmltextview.HtmlTextView;
@ -73,7 +74,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
@BindView(R.id.load_wrapper_view_post_detail) RelativeLayout mLoadWrapper;
@BindView(R.id.progress_bar_view_post_detail) ProgressBar mLoadImageProgressBar;
@BindView(R.id.load_image_error_text_view_view_post_detail) TextView mLoadImageErrorTextView;
@BindView(R.id.image_view_view_post_detail) ImageView mImageView;
@BindView(R.id.image_view_view_post_detail) AspectRatioImageView mImageView;
@BindView(R.id.image_view_no_preview_link_view_post_detail) ImageView mNoPreviewLinkImageView;
@BindView(R.id.plus_button_view_post_detail) ImageView mUpvoteButton;
@ -167,6 +168,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
if(mPostData.getPostType() != PostData.TEXT_TYPE && mPostData.getPostType() != PostData.NO_PREVIEW_LINK_TYPE) {
mRelativeLayout.setVisibility(View.VISIBLE);
mImageView.setVisibility(View.VISIBLE);
mImageView.setRatio((float) mPostData.getPreviewHeight() / (float) mPostData.getPreviewWidth());
loadImage();
}
@ -205,12 +207,6 @@ public class ViewPostDetailActivity extends AppCompatActivity {
if(mPostData.isNSFW()) {
mNSFWTextView.setVisibility(View.VISIBLE);
}
if(!mPostData.getSelfText().equals("")) {
mContentTextView.setVisibility(View.VISIBLE);
mContentTextView.setHtml(mPostData.getSelfText());
}
mScoreTextView.setText(Integer.toString(mPostData.getScore()));
mShareButton.setOnClickListener(new View.OnClickListener() {
@ -298,6 +294,10 @@ public class ViewPostDetailActivity extends AppCompatActivity {
break;
case PostData.NO_PREVIEW_LINK_TYPE:
mTypeTextView.setText("LINK");
if(!mPostData.getSelfText().equals("")) {
mContentTextView.setVisibility(View.VISIBLE);
mContentTextView.setHtml(mPostData.getSelfText());
}
mNoPreviewLinkImageView.setVisibility(View.VISIBLE);
mNoPreviewLinkImageView.setOnClickListener(new View.OnClickListener() {
@Override
@ -313,6 +313,10 @@ public class ViewPostDetailActivity extends AppCompatActivity {
break;
case PostData.TEXT_TYPE:
mTypeTextView.setText("TEXT");
if(!mPostData.getSelfText().equals("")) {
mContentTextView.setVisibility(View.VISIBLE);
mContentTextView.setHtml(mPostData.getSelfText());
}
break;
}
queryComment();
@ -520,7 +524,9 @@ public class ViewPostDetailActivity extends AppCompatActivity {
}
private void loadImage() {
RequestBuilder imageRequestBuilder = Glide.with(this).load(mPostData.getPreviewUrl()).listener(new RequestListener<Drawable>() {
RequestBuilder imageRequestBuilder = Glide.with(this).load(mPostData.getPreviewUrl())
.apply(new RequestOptions().override(mPostData.getPreviewWidth(), mPostData.getPreviewHeight()))
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
mLoadImageProgressBar.setVisibility(View.GONE);

View File

@ -100,6 +100,7 @@
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_centerVertical="true"
android:textSize="12sp"
android:background="@drawable/rounded_corner"
android:textColor="@android:color/white" />
@ -156,7 +157,7 @@
android:layout_marginTop="16dp"
android:visibility="gone">
<ImageView
<com.santalu.aspectratioimageview.AspectRatioImageView
android:id="@+id/image_view_view_post_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -166,7 +167,8 @@
<RelativeLayout
android:id="@+id/load_wrapper_view_post_detail"
android:layout_width="match_parent"
android:layout_height="100dp">
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<ProgressBar
android:id="@+id/progress_bar_view_post_detail"

View File

@ -83,6 +83,7 @@
android:background="@drawable/rounded_corner"
android:layout_marginEnd="8dp"
android:layout_centerVertical="true"
android:textSize="12sp"
android:textColor="@android:color/white"/>
<ImageView
@ -136,7 +137,7 @@
<RelativeLayout
android:id="@+id/image_view_wrapper_item_best_post"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:visibility="gone">
@ -146,11 +147,11 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<ImageView
<com.santalu.aspectratioimageview.AspectRatioImageView
android:id="@+id/image_view_best_post_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
android:layout_height="wrap_content"
android:scaleType="fitStart" />
<LinearLayout
android:id="@+id/load_image_error_linear_layout_best_post_item"

View File

@ -19,6 +19,7 @@ allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}