Error handling for loading posts now works again. Don't show refresh button as an icon. Rewrite some code.

This commit is contained in:
Alex Ning 2018-12-29 13:38:18 +08:00
parent 93a9ad9ece
commit b7e1d92c7e
14 changed files with 251 additions and 299 deletions

View File

@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState />
</value>
</entry>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/home/alex/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/alert/ic_error_outline_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_pin_outline" />
<entry key="sourceFile" value="$USER_HOME$/Downloads/if_pin-outline_216358.svg" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

Binary file not shown.

8
.idea/misc.xml generated
View File

@ -5,22 +5,26 @@
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="5">
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>

2
.idea/vcs.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -2,7 +2,7 @@ package ml.docilealligator.infinityforreddit;
class NetworkState {
public enum Status{
RUNNING,
LOADING,
SUCCESS,
FAILED
}
@ -21,7 +21,7 @@ class NetworkState {
static {
LOADED=new NetworkState(Status.SUCCESS,"Success");
LOADING=new NetworkState(Status.RUNNING,"Running");
LOADING=new NetworkState(Status.LOADING,"Loading");
}
public Status getStatus() {

View File

@ -19,16 +19,21 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
private boolean isBestPost;
private String subredditName;
private MutableLiveData networkState;
private MutableLiveData initialLoading;
private MutableLiveData<NetworkState> paginationNetworkStateLiveData;
private MutableLiveData<NetworkState> initialLoadStateLiveData;
private LoadInitialParams<String> initialParams;
private LoadInitialCallback<String, Post> initialCallback;
private LoadParams<String> params;
private LoadCallback<String, Post> callback;
PostDataSource(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.locale = locale;
this.isBestPost = isBestPost;
networkState = new MutableLiveData();
initialLoading = new MutableLiveData();
paginationNetworkStateLiveData = new MutableLiveData();
initialLoadStateLiveData = new MutableLiveData();
}
@ -37,22 +42,24 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
this.locale = locale;
this.isBestPost = isBestPost;
this.subredditName = subredditName;
networkState = new MutableLiveData();
initialLoading = new MutableLiveData();
paginationNetworkStateLiveData = new MutableLiveData();
initialLoadStateLiveData = new MutableLiveData();
}
MutableLiveData getNetworkState() {
return networkState;
MutableLiveData getPaginationNetworkStateLiveData() {
return paginationNetworkStateLiveData;
}
MutableLiveData getInitialLoading() {
return initialLoading;
MutableLiveData getInitialLoadStateLiveData() {
return initialLoadStateLiveData;
}
@Override
public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull final LoadInitialCallback<String, Post> callback) {
initialLoading.postValue(NetworkState.LOADING);
networkState.postValue(NetworkState.LOADING);
initialParams = params;
initialCallback = callback;
initialLoadStateLiveData.postValue(NetworkState.LOADING);
if(isBestPost) {
RedditAPI api = retrofit.create(RedditAPI.class);
@ -67,26 +74,25 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
@Override
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
callback.onResult(newPosts, null, lastItem);
initialLoading.postValue(NetworkState.LOADED);
networkState.postValue(NetworkState.LOADED);
initialLoadStateLiveData.postValue(NetworkState.LOADED);
}
@Override
public void onParsePostFail() {
Log.i("Post fetch error", "Error parsing data");
initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data"));
}
});
} else {
Log.i("Post fetch error", response.message());
initialLoading.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
String errorMessage = t == null ? "unknown error" : t.getMessage();
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
}
});
} else {
@ -101,26 +107,25 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
@Override
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
callback.onResult(newPosts, null, lastItem);
initialLoading.postValue(NetworkState.LOADED);
networkState.postValue(NetworkState.LOADED);
initialLoadStateLiveData.postValue(NetworkState.LOADED);
}
@Override
public void onParsePostFail() {
Log.i("Post fetch error", "Error parsing data");
initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data"));
}
});
} else {
Log.i("Post fetch error", response.message());
initialLoading.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
String errorMessage = t == null ? "unknown error" : t.getMessage();
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
}
});
}
@ -133,7 +138,10 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
@Override
public void loadAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback) {
networkState.postValue(NetworkState.LOADING);
this.params = params;
this.callback = callback;
paginationNetworkStateLiveData.postValue(NetworkState.LOADING);
if(isBestPost) {
RedditAPI api = retrofit.create(RedditAPI.class);
@ -147,24 +155,25 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
@Override
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
callback.onResult(newPosts, lastItem);
networkState.postValue(NetworkState.LOADED);
paginationNetworkStateLiveData.postValue(NetworkState.LOADED);
}
@Override
public void onParsePostFail() {
Log.i("Best post", "Error parsing data");
paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data"));
}
});
} else {
Log.i("best post", response.message());
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
String errorMessage = t == null ? "unknown error" : t.getMessage();
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
}
});
} else {
@ -178,26 +187,35 @@ class PostDataSource extends PageKeyedDataSource<String, Post> {
@Override
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
callback.onResult(newPosts, lastItem);
networkState.postValue(NetworkState.LOADED);
paginationNetworkStateLiveData.postValue(NetworkState.LOADED);
}
@Override
public void onParsePostFail() {
Log.i("Best post", "Error parsing data");
paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data"));
}
});
} else {
Log.i("best post", response.message());
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
Log.i("Best post", response.message());
paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
String errorMessage = t == null ? "unknown error" : t.getMessage();
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
}
});
}
}
void retry() {
loadInitial(initialParams, initialCallback);
}
void retryLoadingMore() {
loadAfter(params, callback);
}
}

View File

@ -11,40 +11,48 @@ class PostDataSourceFactory extends DataSource.Factory {
private Retrofit retrofit;
private String accessToken;
private Locale locale;
private boolean isBestPost;
private String subredditName;
private MutableLiveData<PostDataSource> mutableLiveData;
private PostDataSource postDataSource;
private MutableLiveData<PostDataSource> postDataSourceLiveData;
PostDataSourceFactory(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
this.retrofit = retrofit;
this.accessToken = accessToken;
this.locale = locale;
this.isBestPost = isBestPost;
mutableLiveData = new MutableLiveData<>();
}
postDataSourceLiveData = new MutableLiveData<>();
PostDataSourceFactory(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) {
this.retrofit = retrofit;
this.locale = locale;
this.isBestPost = isBestPost;
mutableLiveData = new MutableLiveData<>();
this.subredditName = subredditName;
}
@Override
public DataSource create() {
PostDataSource postDataSource;
if(isBestPost) {
postDataSource = new PostDataSource(retrofit, accessToken, locale, isBestPost);
} else {
postDataSource = new PostDataSource(retrofit, locale, isBestPost, subredditName);
}
mutableLiveData.postValue(postDataSource);
}
PostDataSourceFactory(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) {
this.retrofit = retrofit;
this.locale = locale;
this.subredditName = subredditName;
postDataSourceLiveData = new MutableLiveData<>();
if(isBestPost) {
postDataSource = new PostDataSource(retrofit, accessToken, locale, isBestPost);
} else {
postDataSource = new PostDataSource(retrofit, locale, isBestPost, subredditName);
}
}
@Override
public DataSource create() {
postDataSourceLiveData.postValue(postDataSource);
return postDataSource;
}
public MutableLiveData<PostDataSource> getMutableLiveData() {
return mutableLiveData;
public MutableLiveData<PostDataSource> getPostDataSourceLiveData() {
return postDataSourceLiveData;
}
PostDataSource getPostDataSource() {
return postDataSource;
}
}

View File

@ -11,6 +11,7 @@ import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -98,24 +99,15 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
if(!mIsBestPost) {
mSubredditName = getArguments().getString(SUBREDDIT_NAME_KEY);
} else {
/*mFetchPostErrorLinearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mIsBestPost) {
fetchBestPost();
} else {
fetchPost();
}
}
});*/
mFetchPostErrorLinearLayout.setOnClickListener(view -> mPostViewModel.retry());
}
if(mIsBestPost) {
mAdapter = new PostRecyclerViewAdapter(getActivity(), mOauthRetrofit,
mSharedPreferences, mIsBestPost);
mSharedPreferences, mIsBestPost, () -> mPostViewModel.retryLoadingMore());
} else {
mAdapter = new PostRecyclerViewAdapter(getActivity(), mRetrofit,
mSharedPreferences, mIsBestPost);
mSharedPreferences, mIsBestPost, () -> mPostViewModel.retryLoadingMore());
}
mPostRecyclerView.setAdapter(mAdapter);
@ -132,16 +124,23 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
}
mPostViewModel = ViewModelProviders.of(this, factory).get(PostViewModel.class);
mPostViewModel.getPosts().observe(this, posts -> mAdapter.submitList(posts));
mPostViewModel.getInitialLoadingState().observe(this, networkState -> {
if(networkState.getStatus().equals(NetworkState.Status.SUCCESS)) {
mProgressBar.setVisibility(View.GONE);
} else if(networkState.getStatus().equals(NetworkState.Status.FAILED)) {
showErrorView();
} else {
mFetchPostErrorLinearLayout.setVisibility(View.GONE);
mProgressBar.setVisibility(View.VISIBLE);
}
});
mPostViewModel.getPaginationNetworkState().observe(this, networkState -> {
Log.i("networkstate", networkState.getStatus().toString());
mAdapter.setNetworkState(networkState);
});
return rootView;
}
@ -159,16 +158,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
}
} else {
Snackbar snackbar = Snackbar.make(mCoordinatorLayout, "Error getting post", Snackbar.LENGTH_INDEFINITE);
snackbar.setAction(R.string.retry, new View.OnClickListener() {
@Override
public void onClick(View view) {
/*if (mIsBestPost) {
fetchBestPost();
} else {
fetchPost();
}*/
}
});
snackbar.setAction(R.string.retry, view -> mPostViewModel.retry());
snackbar.show();
}
}

View File

@ -21,7 +21,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
@ -36,8 +35,6 @@ import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import java.util.List;
import CustomView.AspectRatioGifImageView;
import SubredditDatabase.SubredditDao;
import SubredditDatabase.SubredditRoomDatabase;
@ -57,16 +54,22 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
private SharedPreferences mSharedPreferences;
private RequestManager glide;
private SubredditDao subredditDao;
private boolean isLoadingMorePostSuccess = true;
private boolean canStartActivity = true;
private boolean hasMultipleSubreddits;
private static final int VIEW_TYPE_DATA = 0;
private static final int VIEW_TYPE_LOADING = 1;
private static final int VIEW_TYPE_ERROR = 1;
private static final int VIEW_TYPE_LOADING = 2;
private NetworkState networkState;
private RetryLoadingMoreCallback retryLoadingMoreCallback;
PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, SharedPreferences sharedPreferences, boolean hasMultipleSubreddits) {
interface RetryLoadingMoreCallback {
void retryLoadingMore();
}
PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, SharedPreferences sharedPreferences, boolean hasMultipleSubreddits,
RetryLoadingMoreCallback retryLoadingMoreCallback) {
super(DIFF_CALLBACK);
if(context != null) {
mContext = context;
@ -75,6 +78,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
this.hasMultipleSubreddits = hasMultipleSubreddits;
glide = Glide.with(mContext.getApplicationContext());
subredditDao = SubredditRoomDatabase.getDatabase(mContext.getApplicationContext()).subredditDao();
this.retryLoadingMoreCallback = retryLoadingMoreCallback;
}
}
@ -100,17 +104,15 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
if(viewType == VIEW_TYPE_DATA) {
CardView cardView = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post, parent, false);
return new DataViewHolder(cardView);
} else if(viewType == VIEW_TYPE_ERROR) {
RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false);
return new ErrorViewHolder(relativeLayout);
} else {
LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_progress_bar, parent, false);
return new LoadingViewHolder(linearLayout);
RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false);
return new LoadingViewHolder(relativeLayout);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
onBindViewHolder(holder, position);
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
if(holder instanceof DataViewHolder) {
@ -129,40 +131,37 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
if(post.getSubredditIconUrl() == null) {
new LoadSubredditIconAsyncTask(subredditDao, subredditName,
new LoadSubredditIconAsyncTask.LoadSubredditIconAsyncTaskListener() {
@Override
public void loadIconSuccess(String iconImageUrl) {
if(mContext != null && getItemCount() > 0) {
if(!iconImageUrl.equals("")) {
glide.load(iconImageUrl)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.error(glide.load(R.drawable.subreddit_default_icon))
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
iconImageUrl -> {
if(mContext != null && getItemCount() > 0) {
if(!iconImageUrl.equals("")) {
glide.load(iconImageUrl)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.error(glide.load(R.drawable.subreddit_default_icon))
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
if(resource instanceof Animatable) {
//This is a gif
//((Animatable) resource).start();
((DataViewHolder) holder).subredditIconGifImageView.startAnimation();
}
return false;
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
if(resource instanceof Animatable) {
//This is a gif
//((Animatable) resource).start();
((DataViewHolder) holder).subredditIconGifImageView.startAnimation();
}
})
.into(((DataViewHolder) holder).subredditIconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((DataViewHolder) holder).subredditIconGifImageView);
}
return false;
}
})
.into(((DataViewHolder) holder).subredditIconGifImageView);
} else {
glide.load(R.drawable.subreddit_default_icon)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
.into(((DataViewHolder) holder).subredditIconGifImageView);
}
if(holder.getAdapterPosition() >= 0) {
post.setSubredditIconUrl(iconImageUrl);
}
if(holder.getAdapterPosition() >= 0) {
post.setSubredditIconUrl(iconImageUrl);
}
}
}).execute();
@ -341,21 +340,18 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
((DataViewHolder) holder).typeTextView.setText("VIDEO");
final Uri videoUri = Uri.parse(post.getVideoUrl());
((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, ViewVideoActivity.class);
intent.setData(videoUri);
intent.putExtra(ViewVideoActivity.TITLE_KEY, title);
intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, post.isDashVideo());
intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, post.isDownloadableGifOrVideo());
if(post.isDownloadableGifOrVideo()) {
intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, post.getGifOrVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName);
intent.putExtra(ViewVideoActivity.ID_KEY, id);
}
mContext.startActivity(intent);
((DataViewHolder) holder).imageView.setOnClickListener(view -> {
Intent intent = new Intent(mContext, ViewVideoActivity.class);
intent.setData(videoUri);
intent.putExtra(ViewVideoActivity.TITLE_KEY, title);
intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, post.isDashVideo());
intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, post.isDownloadableGifOrVideo());
if(post.isDownloadableGifOrVideo()) {
intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, post.getGifOrVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName);
intent.putExtra(ViewVideoActivity.ID_KEY, id);
}
mContext.startActivity(intent);
});
break;
case Post.NO_PREVIEW_LINK_TYPE:
@ -507,36 +503,6 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
}
});
}
} else if(holder instanceof LoadingViewHolder) {
((LoadingViewHolder) holder).retryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//mPaginationSynchronizer.getPaginationRetryNotifier().retry();
((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE);
((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE);
}
});
PaginationNotifier mPaginationNotifier = new PaginationNotifier() {
@Override
public void LoadMorePostSuccess() {
isLoadingMorePostSuccess = true;
}
@Override
public void LoadMorePostFail() {
((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE);
((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE);
isLoadingMorePostSuccess = false;
}
};
/*mPaginationSynchronizer.setPaginationNotifier(mPaginationNotifier);
if(!mPaginationSynchronizer.isLoadingMorePostsSuccess()) {
((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE);
((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE);
}*/
}
}
@ -575,25 +541,42 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
@Override
public int getItemViewType(int position) {
return (position >= getItemCount() ? VIEW_TYPE_LOADING : VIEW_TYPE_DATA);
// Reached at the end
if (hasExtraRow() && position == getItemCount() - 1) {
if (networkState.getStatus() == NetworkState.Status.LOADING) {
return VIEW_TYPE_LOADING;
} else {
return VIEW_TYPE_ERROR;
}
} else {
return VIEW_TYPE_DATA;
}
}
@Override
public int getItemCount() {
if(hasExtraRow()) {
return super.getItemCount() + 1;
}
return super.getItemCount();
}
private boolean hasExtraRow() {
return networkState != null && networkState != NetworkState.LOADED;
return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS;
}
public void setNetworkState(NetworkState newNetworkState) {
void setNetworkState(NetworkState newNetworkState) {
NetworkState previousState = this.networkState;
boolean previousExtraRow = hasExtraRow();
this.networkState = newNetworkState;
boolean newExtraRow = hasExtraRow();
if (previousExtraRow != newExtraRow) {
if (previousExtraRow) {
notifyItemRemoved(getItemCount());
notifyItemRemoved(super.getItemCount());
} else {
notifyItemInserted(getItemCount());
notifyItemInserted(super.getItemCount());
}
} else if (newExtraRow && previousState != newNetworkState) {
} else if (newExtraRow && !previousState.equals(newNetworkState)) {
notifyItemChanged(getItemCount() - 1);
}
}
@ -626,12 +609,21 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
}
}
class LoadingViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.progress_bar_footer_progress_bar_item) ProgressBar progressBar;
class ErrorViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.relative_layout_footer_progress_bar_item) RelativeLayout relativeLayout;
@BindView(R.id.retry_button_footer_progress_bar_item) Button retryButton;
LoadingViewHolder(View itemView) {
ErrorViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
retryButton.setOnClickListener(view -> retryLoadingMoreCallback.retryLoadingMore());
}
}
class LoadingViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.progress_bar_footer_progress_bar_item) ProgressBar progressBar;
LoadingViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
@ -660,14 +652,6 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
((DataViewHolder) holder).noPreviewLinkImageView.setVisibility(View.GONE);
((DataViewHolder) holder).upvoteButton.clearColorFilter();
((DataViewHolder) holder).downvoteButton.clearColorFilter();
} else if(holder instanceof LoadingViewHolder) {
if(isLoadingMorePostSuccess) {
((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE);
((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE);
} else {
((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE);
((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE);
}
}
}
}

View File

@ -9,25 +9,22 @@ import android.arch.paging.PagedList;
import android.support.annotation.NonNull;
import java.util.Locale;
import java.util.concurrent.Executor;
import retrofit2.Retrofit;
public class PostViewModel extends ViewModel {
private Executor executor;
private LiveData<NetworkState> networkState;
private PostDataSource postDataSource;
private LiveData<NetworkState> paginationNetworkState;
private LiveData<NetworkState> initialLoadingState;
private LiveData<PagedList<Post>> posts;
public PostViewModel(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
//executor = Executors.newFixedThreadPool(5);
PostDataSourceFactory postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, isBestPost);
initialLoadingState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(),
dataSource -> dataSource.getInitialLoading());
networkState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(),
dataSource -> dataSource.getNetworkState());
initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(),
dataSource -> dataSource.getInitialLoadStateLiveData());
paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(),
dataSource -> dataSource.getPaginationNetworkStateLiveData());
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder())
.setEnablePlaceholders(false)
@ -35,17 +32,16 @@ public class PostViewModel extends ViewModel {
.build();
posts = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
postDataSource = postDataSourceFactory.getPostDataSource();
}
public PostViewModel(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) {
//executor = Executors.newFixedThreadPool(5);
PostDataSourceFactory postDataSourceFactory = new PostDataSourceFactory(retrofit, locale, isBestPost, subredditName);
initialLoadingState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(),
dataSource -> dataSource.getInitialLoading());
networkState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(),
dataSource -> dataSource.getNetworkState());
initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(),
dataSource -> dataSource.getInitialLoadStateLiveData());
paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(),
dataSource -> dataSource.getPaginationNetworkStateLiveData());
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder())
@ -54,20 +50,29 @@ public class PostViewModel extends ViewModel {
.build();
posts = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
postDataSource = postDataSourceFactory.getPostDataSource();
}
LiveData<PagedList<Post>> getPosts() {
return posts;
}
LiveData<NetworkState> getNetworkState() {
return networkState;
LiveData<NetworkState> getPaginationNetworkState() {
return paginationNetworkState;
}
public LiveData<NetworkState> getInitialLoadingState() {
return initialLoadingState;
}
void retry() {
postDataSource.retry();
}
void retryLoadingMore() {
postDataSource.retryLoadingMore();
}
public static class Factory extends ViewModelProvider.NewInstanceFactory {
private Retrofit retrofit;
private String accessToken;

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_layout_footer_progress_bar_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/retry_button_footer_progress_bar_item"
android:text="@string/load_data_failed"
android:textSize="18sp" />
<Button
android:id="@+id/retry_button_footer_progress_bar_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:text="@string/retry" />
</RelativeLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/progress_bar_footer_progress_bar_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:layout_centerHorizontal="true" />
</RelativeLayout>

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/linear_layout_footer_progress_bar_item"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progress_bar_footer_progress_bar_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:layout_gravity="center" />
<RelativeLayout
android:id="@+id/relative_layout_footer_progress_bar_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="@id/retry_button_footer_progress_bar_item"
android:layout_alignParentStart="true"
android:text="@string/load_data_failed"
android:textSize="18sp"
android:layout_centerVertical="true" />
<Button
android:id="@+id/retry_button_footer_progress_bar_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="@color/colorAccent"
android:text="@string/retry" />
</RelativeLayout>
</LinearLayout>

View File

@ -8,5 +8,5 @@
android:orderInCategory="1"
android:title="@string/action_refresh"
android:icon="@drawable/ic_refresh_white_24dp"
app:showAsAction="always" />
app:showAsAction="never" />
</menu>