From 11ec08c12fbbf20a52dae50359fa520c29d66367 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Tue, 22 Jun 2021 13:16:17 +0800 Subject: Implement two pane layout in ViewPostDetailFragment to separate post detail and comments. Fix bugs related to separating CommentAndPostRecyclerViewAdapter. --- .../adapters/CommentsRecyclerViewAdapter.java | 93 +++--- .../adapters/PostDetailRecyclerViewAdapter.java | 331 ++------------------- .../fragments/ViewPostDetailFragment.java | 136 +++++---- .../res/layout-land/fragment_view_post_detail.xml | 65 ++++ .../layout-sw600dp/fragment_view_post_detail.xml | 65 ++++ .../main/res/layout/fragment_view_post_detail.xml | 4 +- 6 files changed, 287 insertions(+), 407 deletions(-) create mode 100644 app/src/main/res/layout-land/fragment_view_post_detail.xml create mode 100644 app/src/main/res/layout-sw600dp/fragment_view_post_detail.xml (limited to 'app') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java index 4f42b519..965c9844 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java @@ -393,9 +393,9 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter authorTextView.performClick()); moreButton.setOnClickListener(view -> { + getItemCount(); Comment comment = getCurrentComment(this); if (comment != null) { Bundle bundle = new Bundle(); @@ -1447,9 +1448,9 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter= 0 && position < mVisibleComments.size()) { - int childDepth = mVisibleComments.get(position).getDepth(); - for (int i = position; i >= 0; i--) { - if (mVisibleComments.get(i).getDepth() < childDepth) { - return i; - } - } - } - return -1; - } - - private void expandChildren(ArrayList comments, ArrayList newList, int position) { - if (comments != null && comments.size() > 0) { - newList.addAll(position, comments); - for (int i = 0; i < comments.size(); i++) { - position++; - if (comments.get(i).getChildren() != null && comments.get(i).getChildren().size() > 0) { - expandChildren(comments.get(i).getChildren(), newList, position); - position = position + comments.get(i).getChildren().size(); - } - comments.get(i).setExpanded(true); - } - } - } - - private void collapseChildren(int position) { - mVisibleComments.get(position).setExpanded(false); - int depth = mVisibleComments.get(position).getDepth(); - int allChildrenSize = 0; - for (int i = position + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getDepth() > depth) { - allChildrenSize++; - } else { - break; - } - } - - if (allChildrenSize > 0) { - mVisibleComments.subList(position + 1, position + 1 + allChildrenSize).clear(); - } - if (mIsSingleCommentThreadMode) { - if (mFullyCollapseComment) { - notifyItemChanged(position + 2); - } - notifyItemRangeRemoved(position + 3, allChildrenSize); - } else { - if (mFullyCollapseComment) { - notifyItemChanged(position + 1); - } - notifyItemRangeRemoved(position + 2, allChildrenSize); - } - } - - public void addComments(@NonNull ArrayList comments, boolean hasMoreComments) { - if (mVisibleComments.size() == 0) { - isInitiallyLoading = false; - isInitiallyLoadingFailed = false; - if (comments.size() == 0) { - notifyItemChanged(1); - } else { - notifyItemRemoved(1); - } - } - - int sizeBefore = mVisibleComments.size(); - mVisibleComments.addAll(comments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(sizeBefore + 2, comments.size()); - } else { - notifyItemRangeInserted(sizeBefore + 1, comments.size()); - } - - if (mHasMoreComments != hasMoreComments) { - if (hasMoreComments) { - if (mIsSingleCommentThreadMode) { - notifyItemInserted(mVisibleComments.size() + 2); - } else { - notifyItemInserted(mVisibleComments.size() + 1); - } - } else { - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(mVisibleComments.size() + 2); - } else { - notifyItemRemoved(mVisibleComments.size() + 1); - } - } - } - mHasMoreComments = hasMoreComments; - } - - public void addComment(Comment comment) { - if (mVisibleComments.size() == 0 || isInitiallyLoadingFailed) { - notifyItemRemoved(1); - } - - mVisibleComments.add(0, comment); - - if (isInitiallyLoading) { - notifyItemInserted(2); - } else { - notifyItemInserted(1); - } - } - - public void addChildComment(Comment comment, String parentFullname, int parentPosition) { - if (!parentFullname.equals(mVisibleComments.get(parentPosition).getFullName())) { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (parentFullname.equals(mVisibleComments.get(i).getFullName())) { - parentPosition = i; - break; - } - } - } - - mVisibleComments.get(parentPosition).addChild(comment); - mVisibleComments.get(parentPosition).setHasReply(true); - if (!mVisibleComments.get(parentPosition).isExpanded()) { - ArrayList newList = new ArrayList<>(); - expandChildren(mVisibleComments.get(parentPosition).getChildren(), newList, 0); - mVisibleComments.get(parentPosition).setExpanded(true); - mVisibleComments.addAll(parentPosition + 1, newList); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(parentPosition + 2); - notifyItemRangeInserted(parentPosition + 3, newList.size()); - } else { - notifyItemChanged(parentPosition + 1); - notifyItemRangeInserted(parentPosition + 2, newList.size()); - } - } else { - mVisibleComments.add(parentPosition + 1, comment); - if (mIsSingleCommentThreadMode) { - notifyItemInserted(parentPosition + 3); - } else { - notifyItemInserted(parentPosition + 2); - } - } - } - - public void setSingleComment(String singleCommentId, boolean isSingleCommentThreadMode) { - mSingleCommentId = singleCommentId; - mIsSingleCommentThreadMode = isSingleCommentThreadMode; - } - - public ArrayList getVisibleComments() { - return mVisibleComments; - } - - public void initiallyLoading() { - if (mVisibleComments.size() != 0) { - int previousSize = mVisibleComments.size(); - mVisibleComments.clear(); - if (mIsSingleCommentThreadMode) { - notifyItemRangeRemoved(1, previousSize + 1); - } else { - notifyItemRangeRemoved(1, previousSize); - } - } - - if (isInitiallyLoading || isInitiallyLoadingFailed || mVisibleComments.size() == 0) { - isInitiallyLoading = true; - isInitiallyLoadingFailed = false; - notifyItemChanged(1); - } else { - isInitiallyLoading = true; - isInitiallyLoadingFailed = false; - notifyItemInserted(1); - } - } - - public void initiallyLoadCommentsFailed() { - isInitiallyLoading = false; - isInitiallyLoadingFailed = true; - notifyItemChanged(1); - } - - public void loadMoreCommentsFailed() { - loadMoreCommentsFailed = true; - if (mIsSingleCommentThreadMode) { - notifyItemChanged(mVisibleComments.size() + 2); - } else { - notifyItemChanged(mVisibleComments.size() + 1); - } - } - - public void editComment(String commentAuthor, String commentContentMarkdown, int position) { - if (commentAuthor != null) - mVisibleComments.get(position).setAuthor(commentAuthor); - - mVisibleComments.get(position).setCommentMarkdown(commentContentMarkdown); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(position + 2); - } else { - notifyItemChanged(position + 1); - } - } - - public void deleteComment(int position) { - if (mVisibleComments != null && position >= 0 && position < mVisibleComments.size()) { - if (mVisibleComments.get(position).hasReply()) { - mVisibleComments.get(position).setAuthor("[deleted]"); - mVisibleComments.get(position).setCommentMarkdown("[deleted]"); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(position + 2); - } else { - notifyItemChanged(position + 1); - } - } else { - mVisibleComments.remove(position); - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(position + 2); - } else { - notifyItemRemoved(position + 1); - } - } - } - } - public void setBlurNsfwAndDoNotBlurNsfwInNsfwSubreddits(boolean needBlurNsfw, boolean doNotBlurNsfwInNsfwSubreddits) { mNeedBlurNsfw = needBlurNsfw; mDoNotBlurNsfwInNsfwSubreddits = doNotBlurNsfwInNsfwSubreddits; @@ -2044,7 +1761,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter 0) { mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @@ -391,8 +400,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic if (touchHelper != null) { touchHelper.attachToRecyclerView(null); touchHelper.attachToRecyclerView(mRecyclerView); - if (mCommentAdapter != null) { - mCommentAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); + if (mCommentsAdapter != null) { + mCommentsAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); } } } @@ -531,7 +540,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); } }); - mCommentAdapter = new CommentsRecyclerViewAdapter(activity, + mCommentsAdapter = new CommentsRecyclerViewAdapter(activity, this, mCustomThemeWrapper, mRetrofit, mOauthRetrofit, mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences, @@ -549,8 +558,14 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic fetchMoreComments(); } }); - mConcatAdapter = new ConcatAdapter(mPostAdapter, mCommentAdapter); - mRecyclerView.setAdapter(mConcatAdapter); + if (mCommentsRecyclerView != null) { + mRecyclerView.setAdapter(mPostAdapter); + mCommentsRecyclerView.setAdapter(mCommentsAdapter); + } else { + mConcatAdapter = new ConcatAdapter(mPostAdapter, mCommentsAdapter); + mRecyclerView.setAdapter(mConcatAdapter); + } + if (comments == null) { fetchCommentsRespectRecommendedSort(false); @@ -561,7 +576,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } else if (isFetchingComments) { fetchCommentsRespectRecommendedSort(false); } else { - mCommentAdapter.addComments(comments, hasMoreChildren); + mCommentsAdapter.addComments(comments, hasMoreChildren); if (isLoadingMoreChildren) { isLoadingMoreChildren = false; fetchMoreComments(); @@ -670,28 +685,28 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } public void addComment(Comment comment) { - if (mCommentAdapter != null) { - mCommentAdapter.addComment(comment); + if (mCommentsAdapter != null) { + mCommentsAdapter.addComment(comment); } } public void addChildComment(Comment comment, String parentFullname, int parentPosition) { - if (mCommentAdapter != null) { - mCommentAdapter.addChildComment(comment, parentFullname, parentPosition); + if (mCommentsAdapter != null) { + mCommentsAdapter.addChildComment(comment, parentFullname, parentPosition); } } public void editComment(String commentAuthor, String commentContentMarkdown, int position) { - if (mCommentAdapter != null) { - mCommentAdapter.editComment(commentAuthor, + if (mCommentsAdapter != null) { + mCommentsAdapter.editComment(commentAuthor, commentContentMarkdown, position); } } public void awardGiven(String awardsHTML, int awardCount, int position) { - if (mCommentAdapter != null) { - mCommentAdapter.giveAward(awardsHTML, awardCount, position); + if (mCommentsAdapter != null) { + mCommentsAdapter.giveAward(awardsHTML, awardCount, position); } } @@ -743,8 +758,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } public void saveComment(int position, boolean isSaved) { - if (mCommentAdapter != null) { - mCommentAdapter.setSaveComment(position, isSaved); + if (mCommentsAdapter != null) { + mCommentsAdapter.setSaveComment(position, isSaved); } } @@ -1009,7 +1024,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onResume() { super.onResume(); - if (mCommentAdapter != null && mRecyclerView != null) { + if (mRecyclerView != null) { mRecyclerView.onWindowVisibilityChanged(View.VISIBLE); } } @@ -1017,7 +1032,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onPause() { super.onPause(); - if (mCommentAdapter != null && mRecyclerView != null) { + if (mRecyclerView != null) { mRecyclerView.onWindowVisibilityChanged(View.GONE); } } @@ -1025,7 +1040,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - comments = mCommentAdapter == null ? null : mCommentAdapter.getVisibleComments(); + comments = mCommentsAdapter == null ? null : mCommentsAdapter.getVisibleComments(); Bridge.saveInstanceState(this, outState); } @@ -1107,7 +1122,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } }); - mCommentAdapter = new CommentsRecyclerViewAdapter(activity, + mCommentsAdapter = new CommentsRecyclerViewAdapter(activity, ViewPostDetailFragment.this, mCustomThemeWrapper, mRetrofit, mOauthRetrofit, mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences, @@ -1125,8 +1140,13 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic fetchMoreComments(); } }); - mConcatAdapter = new ConcatAdapter(mPostAdapter, mCommentAdapter); - mRecyclerView.setAdapter(mConcatAdapter); + if (mCommentsRecyclerView != null) { + mRecyclerView.setAdapter(mPostAdapter); + mCommentsRecyclerView.setAdapter(mCommentsAdapter); + } else { + mConcatAdapter = new ConcatAdapter(mPostAdapter, mCommentsAdapter); + mRecyclerView.setAdapter(mConcatAdapter); + } if (mRespectSubredditRecommendedSortType) { fetchCommentsRespectRecommendedSort(false); @@ -1138,7 +1158,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic ViewPostDetailFragment.this.children = moreChildrenFullnames; hasMoreChildren = children.size() != 0; - mCommentAdapter.addComments(expandedComments, hasMoreChildren); + mCommentsAdapter.addComments(expandedComments, hasMoreChildren); if (children.size() > 0) { mRecyclerView.clearOnScrollListeners(); @@ -1189,7 +1209,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onParseCommentFailed() { - mCommentAdapter.initiallyLoadCommentsFailed(); + mCommentsAdapter.initiallyLoadCommentsFailed(); } }); } @@ -1251,8 +1271,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic private void fetchComments(boolean changeRefreshState, boolean checkSortState, String sortType) { isFetchingComments = true; - mCommentAdapter.setSingleComment(mSingleCommentId, isSingleCommentThreadMode); - mCommentAdapter.initiallyLoading(); + mCommentsAdapter.setSingleComment(mSingleCommentId, isSingleCommentThreadMode); + mCommentsAdapter.initiallyLoading(); String commentId = null; if (isSingleCommentThreadMode) { commentId = mSingleCommentId; @@ -1276,7 +1296,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic comments = expandedComments; hasMoreChildren = children.size() != 0; - mCommentAdapter.addComments(expandedComments, hasMoreChildren); + mCommentsAdapter.addComments(expandedComments, hasMoreChildren); if (children.size() > 0) { mRecyclerView.clearOnScrollListeners(); @@ -1341,7 +1361,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic return; } - mCommentAdapter.initiallyLoadCommentsFailed(); + mCommentsAdapter.initiallyLoadCommentsFailed(); if (changeRefreshState) { isRefreshing = false; } @@ -1366,7 +1386,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void onFetchMoreCommentSuccess(ArrayList expandedComments, int childrenStartingIndex) { hasMoreChildren = childrenStartingIndex < children.size(); - mCommentAdapter.addComments(expandedComments, hasMoreChildren); + mCommentsAdapter.addComments(expandedComments, hasMoreChildren); mChildrenStartingIndex = childrenStartingIndex; isLoadingMoreChildren = false; loadMoreChildrenSuccess = true; @@ -1376,7 +1396,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic public void onFetchMoreCommentFailed() { isLoadingMoreChildren = false; loadMoreChildrenSuccess = false; - mCommentAdapter.loadMoreCommentsFailed(); + mCommentsAdapter.loadMoreCommentsFailed(); } }); } @@ -1599,7 +1619,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic @Override public void deleteSuccess() { Toast.makeText(activity, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); - mCommentAdapter.deleteComment(position); + mCommentsAdapter.deleteComment(position); } @Override @@ -1619,7 +1639,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic new FetchRemovedComment.FetchRemovedCommentListener() { @Override public void fetchSuccess(Comment comment) { - mCommentAdapter.editComment(comment.getAuthor(), comment.getCommentMarkdown(), position); + mCommentsAdapter.editComment(comment.getAuthor(), comment.getCommentMarkdown(), position); } @Override @@ -1639,8 +1659,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic public void scrollToNextParentComment() { if (mLinearLayoutManager != null) { int currentPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - if (mCommentAdapter != null) { - int nextParentPosition = mCommentAdapter.getNextParentCommentPosition(currentPosition); + if (mCommentsAdapter != null) { + int nextParentPosition = mCommentsAdapter.getNextParentCommentPosition(currentPosition); if (nextParentPosition < 0) { return; } @@ -1656,8 +1676,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic public void scrollToPreviousParentComment() { if (mLinearLayoutManager != null) { int currentPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - if (mCommentAdapter != null) { - int nextParentPosition = mCommentAdapter.getPreviousParentCommentPosition(currentPosition); + if (mCommentsAdapter != null) { + int nextParentPosition = mCommentsAdapter.getPreviousParentCommentPosition(currentPosition); if (nextParentPosition < 0) { return; } @@ -1725,7 +1745,11 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic if (mPostAdapter != null) { mPostAdapter.setBlurNsfwAndDoNotBlurNsfwInNsfwSubreddits(event.needBlurNSFW, event.doNotBlurNsfwInNsfwSubreddits); } - refreshAdapter(); + if (mCommentsRecyclerView != null) { + refreshAdapter(mRecyclerView, mConcatAdapter); + } else { + refreshAdapter(mRecyclerView, mPostAdapter); + } } @Subscribe @@ -1733,23 +1757,27 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic if (mPostAdapter != null) { mPostAdapter.setBlurSpoiler(event.needBlurSpoiler); } - refreshAdapter(); + if (mCommentsRecyclerView != null) { + refreshAdapter(mRecyclerView, mConcatAdapter); + } else { + refreshAdapter(mRecyclerView, mPostAdapter); + } } - private void refreshAdapter() { + private void refreshAdapter(RecyclerView recyclerView, RecyclerView.Adapter adapter) { int previousPosition = -1; - if (mLinearLayoutManager != null) { - previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + if (recyclerView.getLayoutManager() != null) { + previousPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition(); } - RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager(); - mRecyclerView.setAdapter(null); - mRecyclerView.setLayoutManager(null); - mRecyclerView.setAdapter(mConcatAdapter); - mRecyclerView.setLayoutManager(layoutManager); + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + recyclerView.setAdapter(null); + recyclerView.setLayoutManager(null); + recyclerView.setAdapter(adapter); + recyclerView.setLayoutManager(layoutManager); if (previousPosition > 0) { - mRecyclerView.scrollToPosition(previousPosition); + recyclerView.scrollToPosition(previousPosition); } } @@ -1769,7 +1797,11 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } if (stateChanged) { - refreshAdapter(); + if (mCommentsRecyclerView != null) { + refreshAdapter(mRecyclerView, mConcatAdapter); + } else { + refreshAdapter(mRecyclerView, mPostAdapter); + } } } } diff --git a/app/src/main/res/layout-land/fragment_view_post_detail.xml b/app/src/main/res/layout-land/fragment_view_post_detail.xml new file mode 100644 index 00000000..dd7e1ac5 --- /dev/null +++ b/app/src/main/res/layout-land/fragment_view_post_detail.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-sw600dp/fragment_view_post_detail.xml b/app/src/main/res/layout-sw600dp/fragment_view_post_detail.xml new file mode 100644 index 00000000..dd7e1ac5 --- /dev/null +++ b/app/src/main/res/layout-sw600dp/fragment_view_post_detail.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_view_post_detail.xml b/app/src/main/res/layout/fragment_view_post_detail.xml index 7b2c314a..7875516b 100644 --- a/app/src/main/res/layout/fragment_view_post_detail.xml +++ b/app/src/main/res/layout/fragment_view_post_detail.xml @@ -13,9 +13,9 @@ app:layout_behavior="@string/appbar_scrolling_view_behavior"> -- cgit v1.2.3