From bfb311d75fbe704e9db5aae04ceeb91315fb3ba1 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Mon, 24 Sep 2018 17:03:57 +0800 Subject: Add a feature which is refreshing the posts by clicking the refresh button. Minor bugs fixed. Rewrite some code. --- .../infinityforreddit/FragmentCommunicator.java | 5 + .../infinityforreddit/MainActivity.java | 22 ++++ .../infinityforreddit/PaginationSynchronizer.java | 3 +- .../infinityforreddit/PostFragment.java | 118 +++++++++++---------- .../PostPaginationScrollListener.java | 36 ++++--- .../infinityforreddit/PostRecyclerViewAdapter.java | 29 ++--- .../SubscribedSubredditRecyclerViewAdapter.java | 12 ++- .../ViewSubredditDetailActivity.java | 11 ++ .../main/res/drawable/ic_refresh_white_24dp.xml | 5 + app/src/main/res/menu/main_activity.xml | 12 +++ .../res/menu/view_subreddit_detail_activity.xml | 12 +++ app/src/main/res/values/strings.xml | 1 + 12 files changed, 177 insertions(+), 89 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/FragmentCommunicator.java create mode 100644 app/src/main/res/drawable/ic_refresh_white_24dp.xml create mode 100644 app/src/main/res/menu/main_activity.xml create mode 100644 app/src/main/res/menu/view_subreddit_detail_activity.xml (limited to 'app') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FragmentCommunicator.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FragmentCommunicator.java new file mode 100644 index 00000000..019a6f0d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FragmentCommunicator.java @@ -0,0 +1,5 @@ +package ml.docilealligator.infinityforreddit; + +interface FragmentCommunicator { + void refresh(); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java index 1ea0c809..606126fe 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java @@ -16,6 +16,8 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.widget.ImageView; import android.widget.TextView; @@ -55,6 +57,8 @@ public class MainActivity extends AppCompatActivity { private boolean mFetchUserInfoSuccess; private boolean mInsertSuccess; + private FragmentCommunicator mFragmentCommunicator; + private SubscribedSubredditViewModel mSubscribedSubredditViewModel; private SubscribedUserViewModel mSubscribedUserViewModel; @@ -254,6 +258,24 @@ public class MainActivity extends AppCompatActivity { } } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main_activity, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_refresh_main_activity: + if(mFragment instanceof FragmentCommunicator) { + ((FragmentCommunicator) mFragment).refresh(); + } + return true; + } + return false; + } + @Override public void onBackPressed() { DrawerLayout drawer = findViewById(R.id.drawer_layout); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PaginationSynchronizer.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PaginationSynchronizer.java index 83fa6b10..15346dfc 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PaginationSynchronizer.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PaginationSynchronizer.java @@ -10,9 +10,10 @@ class PaginationSynchronizer implements Parcelable { private PaginationRetryNotifier paginationRetryNotifier; private LastItemSynchronizer lastItemSynchronizer; - PaginationSynchronizer() { + PaginationSynchronizer(LastItemSynchronizer lastItemSynchronizer) { loadingState = false; loadSuccess = true; + this. lastItemSynchronizer = lastItemSynchronizer; } protected PaginationSynchronizer(Parcel in) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java index 3c67787b..8ddbd717 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java @@ -6,7 +6,6 @@ import android.content.ClipboardManager; import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; @@ -33,61 +32,36 @@ import retrofit2.converter.scalars.ScalarsConverterFactory; /** * A simple {@link Fragment} subclass. */ -public class PostFragment extends Fragment { +public class PostFragment extends Fragment implements FragmentCommunicator { static final String SUBREDDIT_NAME_KEY = "SNK"; static final String IS_BEST_POST_KEY = "IBPK"; + private static final String PostDataParcelableState = "BPDPS"; + private static final String lastItemState = "LIS"; + private static final String paginationSynchronizerState = "PSS"; + private CoordinatorLayout mCoordinatorLayout; private RecyclerView mPostRecyclerView; private LinearLayoutManager mLinearLayoutManager; private ProgressBar mProgressBar; + private LinearLayout mFetchPostErrorLinearLayout; + private ImageView mFetchPostErrorImageView; + private ArrayList mPostData; private String mLastItem; private PaginationSynchronizer mPaginationSynchronizer; - private PostRecyclerViewAdapter mAdapter; - private LinearLayout mFetchPostErrorLinearLayout; - private ImageView mFetchPostErrorImageView; private boolean mIsBestPost; private String mSubredditName; - private String PostDataParcelableState = "BPDPS"; - private String lastItemState = "LIS"; - private String paginationSynchronizerState = "PSS"; public PostFragment() { // Required empty public constructor } - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - if(savedInstanceState != null) { - if(savedInstanceState.containsKey(PostDataParcelableState)) { - mPostData = savedInstanceState.getParcelableArrayList(PostDataParcelableState); - mLastItem = savedInstanceState.getString(lastItemState); - mAdapter = new PostRecyclerViewAdapter(getActivity(), mPostData, mPaginationSynchronizer); - mPostRecyclerView.setAdapter(mAdapter); - mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener( - getActivity(), mLinearLayoutManager, mAdapter, mLastItem, mPostData, - mPaginationSynchronizer, mSubredditName, mIsBestPost, - mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadSuccess(), - getResources().getConfiguration().locale)); - mProgressBar.setVisibility(View.GONE); - } else { - if(mIsBestPost) { - fetchBestPost(1); - } else { - fetchPost(); - } - } - } - } - @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - if(mPostData != null) { outState.putParcelableArrayList(PostDataParcelableState, mPostData); outState.putString(lastItemState, mLastItem); @@ -98,13 +72,13 @@ public class PostFragment extends Fragment { @Override public void onResume() { super.onResume(); - if(mAdapter != null) { - mAdapter.setCanStartActivity(true); + if(mPostRecyclerView.getAdapter() != null) { + ((PostRecyclerViewAdapter) mPostRecyclerView.getAdapter()).setCanStartActivity(true); } } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.fragment_post, container, false); @@ -140,10 +114,25 @@ public class PostFragment extends Fragment { }); } - if(savedInstanceState != null && savedInstanceState.getParcelable(paginationSynchronizerState) != null) { + if(savedInstanceState != null && savedInstanceState.containsKey(PostDataParcelableState)) { + mPostData = savedInstanceState.getParcelableArrayList(PostDataParcelableState); + mLastItem = savedInstanceState.getString(lastItemState); mPaginationSynchronizer = savedInstanceState.getParcelable(paginationSynchronizerState); + PostRecyclerViewAdapter adapter = new PostRecyclerViewAdapter(getActivity(), mPostData, mPaginationSynchronizer); + mPostRecyclerView.setAdapter(adapter); + mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener( + getActivity(), mLinearLayoutManager, adapter, mLastItem, mPostData, + mPaginationSynchronizer, mSubredditName, mIsBestPost, + mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadSuccess(), + getResources().getConfiguration().locale)); + mProgressBar.setVisibility(View.GONE); } else { - mPaginationSynchronizer = new PaginationSynchronizer(); + mPaginationSynchronizer = new PaginationSynchronizer(new LastItemSynchronizer() { + @Override + public void lastItemChanged(String lastItem) { + mLastItem = lastItem; + } + }); if(mIsBestPost) { fetchBestPost(1); } else { @@ -151,14 +140,6 @@ public class PostFragment extends Fragment { } } - LastItemSynchronizer lastItemSynchronizer = new LastItemSynchronizer() { - @Override - public void lastItemChanged(String lastItem) { - mLastItem = lastItem; - } - }; - mPaginationSynchronizer.setLastItemSynchronizer(lastItemSynchronizer); - return rootView; } @@ -197,11 +178,11 @@ public class PostFragment extends Fragment { if(isAdded() && getActivity() != null) { mPostData = postData; mLastItem = lastItem; - mAdapter = new PostRecyclerViewAdapter(getActivity(), postData, mPaginationSynchronizer); + PostRecyclerViewAdapter adapter = new PostRecyclerViewAdapter(getActivity(), postData, mPaginationSynchronizer); - mPostRecyclerView.setAdapter(mAdapter); + mPostRecyclerView.setAdapter(adapter); mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener( - getActivity(), mLinearLayoutManager, mAdapter, lastItem, postData, + getActivity(), mLinearLayoutManager, adapter, lastItem, postData, mPaginationSynchronizer, mSubredditName, mIsBestPost, mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadSuccess(), getResources().getConfiguration().locale)); @@ -269,11 +250,11 @@ public class PostFragment extends Fragment { if(isAdded() && getActivity() != null) { mPostData = postData; mLastItem = lastItem; - mAdapter = new PostRecyclerViewAdapter(getActivity(), postData, mPaginationSynchronizer); + PostRecyclerViewAdapter adapter = new PostRecyclerViewAdapter(getActivity(), postData, mPaginationSynchronizer); - mPostRecyclerView.setAdapter(mAdapter); + mPostRecyclerView.setAdapter(adapter); mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener( - getActivity(), mLinearLayoutManager, mAdapter, lastItem, postData, + getActivity(), mLinearLayoutManager, adapter, lastItem, postData, mPaginationSynchronizer, mSubredditName, mIsBestPost, mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadSuccess(), getResources().getConfiguration().locale)); @@ -304,8 +285,10 @@ public class PostFragment extends Fragment { private void showErrorView() { mProgressBar.setVisibility(View.GONE); if(mIsBestPost) { - mFetchPostErrorLinearLayout.setVisibility(View.VISIBLE); - Glide.with(this).load(R.drawable.load_post_error_indicator).into(mFetchPostErrorImageView); + if(getActivity() != null && isAdded()) { + mFetchPostErrorLinearLayout.setVisibility(View.VISIBLE); + Glide.with(this).load(R.drawable.load_post_error_indicator).into(mFetchPostErrorImageView); + } } else { Snackbar snackbar = Snackbar.make(mCoordinatorLayout, "Error getting post", Snackbar.LENGTH_INDEFINITE); snackbar.setAction(R.string.retry, new View.OnClickListener() { @@ -321,4 +304,29 @@ public class PostFragment extends Fragment { snackbar.show(); } } + + @Override + public void refresh() { + mLastItem = null; + mPaginationSynchronizer = new PaginationSynchronizer(new LastItemSynchronizer() { + @Override + public void lastItemChanged(String lastItem) { + mLastItem = lastItem; + } + }); + mPostRecyclerView.clearOnScrollListeners(); + mPostRecyclerView.getRecycledViewPool().clear(); + if(mPostData != null) { + mPostData.clear(); + } + mPostData = null; + if(mPostRecyclerView.getAdapter() != null) { + (mPostRecyclerView.getAdapter()).notifyDataSetChanged(); + } + if(mIsBestPost) { + fetchBestPost(1); + } else { + fetchPost(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java index a6cbf578..a647a60c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java @@ -117,14 +117,16 @@ class PostPaginationScrollListener extends RecyclerView.OnScrollListener { ParsePost.parsePost(response.body(), mPostData, locale, new ParsePost.ParsePostListener() { @Override public void onParsePostSuccess(ArrayList postData, String lastItem) { - mAdapter.notifyItemRangeInserted(mPostData.size(), postData.size()); - mLastItem = lastItem; - mLastItemSynchronizer.lastItemChanged(mLastItem); - - isLoading = false; - loadSuccess = true; - mPaginationSynchronizer.setLoading(false); - mPaginationSynchronizer.setLoadingState(true); + if(mAdapter != null) { + mAdapter.notifyItemRangeInserted(mPostData.size(), postData.size()); + mLastItem = lastItem; + mLastItemSynchronizer.lastItemChanged(lastItem); + + isLoading = false; + loadSuccess = true; + mPaginationSynchronizer.setLoading(false); + mPaginationSynchronizer.setLoadingState(true); + } } @Override @@ -188,14 +190,16 @@ class PostPaginationScrollListener extends RecyclerView.OnScrollListener { ParsePost.parsePost(response.body(), mPostData, locale, new ParsePost.ParsePostListener() { @Override public void onParsePostSuccess(ArrayList postData, String lastItem) { - mAdapter.notifyItemRangeInserted(mPostData.size(), postData.size()); - mLastItem = lastItem; - mLastItemSynchronizer.lastItemChanged(mLastItem); - - isLoading = false; - loadSuccess = true; - mPaginationSynchronizer.setLoading(false); - mPaginationSynchronizer.setLoadingState(true); + if(mAdapter != null) { + mAdapter.notifyItemRangeInserted(mPostData.size(), postData.size()); + mLastItem = lastItem; + mLastItemSynchronizer.lastItemChanged(lastItem); + + isLoading = false; + loadSuccess = true; + mPaginationSynchronizer.setLoading(false); + mPaginationSynchronizer.setLoadingState(true); + } } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java index 3292852b..aeaa3ae0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -83,10 +83,10 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter= 0) { + Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, mSubscribedSubredditData.get(viewHolder.getAdapterPosition()).getName()); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY, mSubscribedSubredditData.get(viewHolder.getAdapterPosition()).getId()); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, true); + mContext.startActivity(intent); + } } }); if(!mSubscribedSubredditData.get(i).getIconUrl().equals("")) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java index af367793..ad627c8e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java @@ -11,6 +11,7 @@ import android.support.design.widget.CollapsingToolbarLayout; import android.support.v4.app.Fragment; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -195,12 +196,22 @@ public class ViewSubredditDetailActivity extends AppCompatActivity { } } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.view_subreddit_detail_activity, menu); + return true; + } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true; + case R.id.action_refresh_view_subreddit_detail_activity: + if(mFragment instanceof FragmentCommunicator) { + ((FragmentCommunicator) mFragment).refresh(); + } } return false; } diff --git a/app/src/main/res/drawable/ic_refresh_white_24dp.xml b/app/src/main/res/drawable/ic_refresh_white_24dp.xml new file mode 100644 index 00000000..cc2d1e04 --- /dev/null +++ b/app/src/main/res/drawable/ic_refresh_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/menu/main_activity.xml b/app/src/main/res/menu/main_activity.xml new file mode 100644 index 00000000..ed6a2e33 --- /dev/null +++ b/app/src/main/res/menu/main_activity.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/view_subreddit_detail_activity.xml b/app/src/main/res/menu/view_subreddit_detail_activity.xml new file mode 100644 index 00000000..aa3537f5 --- /dev/null +++ b/app/src/main/res/menu/view_subreddit_detail_activity.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 34ac12f2..3616ff91 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,6 +7,7 @@ Settings Download + Refresh Error loading posts.\nTap to retry. -- cgit v1.2.3