From 82a64ddb961089d4a0311dc340f68e0e6c7d1cc2 Mon Sep 17 00:00:00 2001 From: Floens Date: Sun, 2 Aug 2015 12:13:07 +0200 Subject: [PATCH] Add collapsing of the toolbar on scroll --- .../chan/controller/ControllerLogic.java | 19 ++-- .../chan/controller/NavigationController.java | 14 +++ .../controller/PopControllerTransition.java | 2 +- .../controller/PushControllerTransition.java | 2 +- .../chan/core/presenter/ThreadPresenter.java | 2 +- .../chan/ui/controller/ThreadController.java | 12 +++ .../floens/chan/ui/layout/ThreadLayout.java | 20 +++-- .../chan/ui/layout/ThreadListLayout.java | 88 +++++++++++++------ .../chan/ui/toolbar/NavigationItem.java | 1 + .../org/floens/chan/ui/toolbar/Toolbar.java | 59 +++++++++++++ .../org/floens/chan/utils/AndroidUtils.java | 5 ++ .../layout/controller_navigation_drawer.xml | 10 +-- .../controller_navigation_image_viewer.xml | 10 +-- 13 files changed, 190 insertions(+), 54 deletions(-) diff --git a/Clover/app/src/main/java/org/floens/chan/controller/ControllerLogic.java b/Clover/app/src/main/java/org/floens/chan/controller/ControllerLogic.java index bc25f1ee..02f8847d 100644 --- a/Clover/app/src/main/java/org/floens/chan/controller/ControllerLogic.java +++ b/Clover/app/src/main/java/org/floens/chan/controller/ControllerLogic.java @@ -23,14 +23,21 @@ import org.floens.chan.utils.AndroidUtils; public class ControllerLogic { public static void attach(Controller controller, ViewGroup view, boolean over) { + ViewGroup.LayoutParams params = controller.view.getLayoutParams(); + + if (params == null) { + params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + } else { + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.MATCH_PARENT; + } + + controller.view.setLayoutParams(params); + if (over) { - view.addView(controller.view, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) - ); + view.addView(controller.view, controller.view.getLayoutParams()); } else { - view.addView(controller.view, 0, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) - ); + view.addView(controller.view, 0, controller.view.getLayoutParams()); } } diff --git a/Clover/app/src/main/java/org/floens/chan/controller/NavigationController.java b/Clover/app/src/main/java/org/floens/chan/controller/NavigationController.java index 912ae9ec..9b6a75e5 100644 --- a/Clover/app/src/main/java/org/floens/chan/controller/NavigationController.java +++ b/Clover/app/src/main/java/org/floens/chan/controller/NavigationController.java @@ -80,6 +80,8 @@ public abstract class NavigationController extends Controller implements Control toolbar.setNavigationItem(false, true, to.navigationItem); } + updateToolbarCollapse(to, controllerTransition != null); + controllerPushed(to); return true; @@ -128,6 +130,8 @@ public abstract class NavigationController extends Controller implements Control } if (to != null) { + updateToolbarCollapse(to, controllerTransition != null); + controllerPopped(to); } @@ -224,4 +228,14 @@ public abstract class NavigationController extends Controller implements Control @Override public void onSearchEntered(String entered) { } + + private void updateToolbarCollapse(Controller controller, boolean animate) { + if (!controller.navigationItem.collapseToolbar) { + FrameLayout.LayoutParams toViewParams = (FrameLayout.LayoutParams) controller.view.getLayoutParams(); + toViewParams.topMargin = toolbar.getToolbarHeight(); + controller.view.setLayoutParams(toViewParams); + } + + toolbar.processScrollCollapse(Toolbar.TOOLBAR_COLLAPSE_SHOW, animate); + } } diff --git a/Clover/app/src/main/java/org/floens/chan/controller/PopControllerTransition.java b/Clover/app/src/main/java/org/floens/chan/controller/PopControllerTransition.java index 61fcba25..7349fe3f 100644 --- a/Clover/app/src/main/java/org/floens/chan/controller/PopControllerTransition.java +++ b/Clover/app/src/main/java/org/floens/chan/controller/PopControllerTransition.java @@ -36,7 +36,7 @@ public class PopControllerTransition extends ControllerTransition { toAlpha.setInterpolator(new DecelerateInterpolator()); // new PathInterpolator(0f, 0f, 0.2f, 1f) toAlpha.setDuration(250); - Animator fromY = ObjectAnimator.ofFloat(from.view, View.Y, 0f, from.view.getHeight() * 0.05f); + Animator fromY = ObjectAnimator.ofFloat(from.view, View.TRANSLATION_Y, 0f, from.view.getHeight() * 0.05f); fromY.setInterpolator(new AccelerateInterpolator(2.5f)); fromY.setDuration(250); diff --git a/Clover/app/src/main/java/org/floens/chan/controller/PushControllerTransition.java b/Clover/app/src/main/java/org/floens/chan/controller/PushControllerTransition.java index 1a56dfc8..939fd705 100644 --- a/Clover/app/src/main/java/org/floens/chan/controller/PushControllerTransition.java +++ b/Clover/app/src/main/java/org/floens/chan/controller/PushControllerTransition.java @@ -41,7 +41,7 @@ public class PushControllerTransition extends ControllerTransition { toAlpha.setDuration(200); toAlpha.setInterpolator(new DecelerateInterpolator(2f)); - Animator toY = ObjectAnimator.ofFloat(to.view, View.Y, to.view.getHeight() * 0.08f, 0f); + Animator toY = ObjectAnimator.ofFloat(to.view, View.TRANSLATION_Y, to.view.getHeight() * 0.08f, 0f); toY.setDuration(350); toY.setInterpolator(new DecelerateInterpolator(2.5f)); diff --git a/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java b/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java index 19ad16b3..d20785d8 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java +++ b/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java @@ -54,7 +54,7 @@ import java.util.List; import static org.floens.chan.utils.AndroidUtils.getString; -public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapter.PostAdapterCallback, PostCellInterface.PostCellCallback, ThreadStatusCell.Callback, ThreadListLayout.ThreadListLayoutCallback { +public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapter.PostAdapterCallback, PostCellInterface.PostCellCallback, ThreadStatusCell.Callback, ThreadListLayout.ThreadListLayoutPresenterCallback { private static final int POST_OPTION_QUOTE = 0; private static final int POST_OPTION_QUOTE_TEXT = 1; private static final int POST_OPTION_INFO = 2; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java index 22a1fadd..030ae2ea 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java @@ -33,6 +33,7 @@ import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.PostImage; import org.floens.chan.ui.helper.RefreshUIMessage; import org.floens.chan.ui.layout.ThreadLayout; +import org.floens.chan.ui.toolbar.Toolbar; import org.floens.chan.ui.view.ThumbnailView; import org.floens.chan.utils.Logger; @@ -40,6 +41,8 @@ import java.util.List; import de.greenrobot.event.EventBus; +import static org.floens.chan.utils.AndroidUtils.dp; + public abstract class ThreadController extends Controller implements ThreadLayout.ThreadLayoutCallback, ImageViewerController.PreviewCallback, RootNavigationController.DrawerCallback, SwipeRefreshLayout.OnRefreshListener, RootNavigationController.ToolbarSearchCallback, NfcAdapter.CreateNdefMessageCallback { private static final String TAG = "ThreadController"; @@ -56,6 +59,8 @@ public abstract class ThreadController extends Controller implements ThreadLayou EventBus.getDefault().register(this); + navigationItem.collapseToolbar = true; + threadLayout = (ThreadLayout) LayoutInflater.from(context).inflate(R.layout.layout_thread, null); threadLayout.setCallback(this); @@ -68,6 +73,8 @@ public abstract class ThreadController extends Controller implements ThreadLayou swipeRefreshLayout.addView(threadLayout); swipeRefreshLayout.setOnRefreshListener(this); + int toolbarHeight = navigationController.toolbar.getToolbarHeight(); + swipeRefreshLayout.setProgressViewOffset(false, toolbarHeight - dp(40), toolbarHeight + dp(64 - 40)); view = swipeRefreshLayout; } @@ -177,6 +184,11 @@ public abstract class ThreadController extends Controller implements ThreadLayou swipeRefreshLayout.setRefreshing(false); } + @Override + public Toolbar getToolbar() { + return navigationController.toolbar; + } + @Override public void onSearchVisibilityChanged(boolean visible) { threadLayout.getPresenter().onSearchVisibilityChanged(visible); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java index 6dada9dd..9e28c41c 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java @@ -58,6 +58,7 @@ import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.ui.adapter.PostsFilter; import org.floens.chan.ui.cell.PostCellInterface; import org.floens.chan.ui.helper.PostPopupHelper; +import org.floens.chan.ui.toolbar.Toolbar; import org.floens.chan.ui.view.LoadView; import org.floens.chan.ui.view.ThumbnailView; import org.floens.chan.utils.AndroidUtils; @@ -72,7 +73,7 @@ import static org.floens.chan.utils.AndroidUtils.getString; /** * Wrapper around ThreadListLayout, so that it cleanly manages between loadbar and listview. */ -public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.ThreadPresenterCallback, PostPopupHelper.PostPopupHelperCallback, View.OnClickListener, ThreadListLayout.ReplyLayoutStateCallback { +public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.ThreadPresenterCallback, PostPopupHelper.PostPopupHelperCallback, View.OnClickListener, ThreadListLayout.ThreadListLayoutCallback { private enum Visible { LOADING, THREAD, @@ -114,9 +115,9 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T init(); } - @Override - protected void onFinishInflate() { - super.onFinishInflate(); + public void setCallback(ThreadLayoutCallback callback) { + this.callback = callback; + presenter = new ThreadPresenter(this); loadView = (LoadView) findViewById(R.id.loadview); @@ -159,10 +160,6 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T return threadListLayout.onBack(); } - public void setCallback(ThreadLayoutCallback callback) { - this.callback = callback; - } - public ThreadPresenter getPresenter() { return presenter; } @@ -181,6 +178,11 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T showReplyButton(!open); } + @Override + public Toolbar getToolbar() { + return callback.getToolbar(); + } + @Override public void showPosts(ChanThread thread, PostsFilter filter) { threadListLayout.showPosts(thread, filter, visible != Visible.THREAD); @@ -492,5 +494,7 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T void presentRepliesController(Controller controller); void hideSwipeRefreshLayout(); + + Toolbar getToolbar(); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java index 3376c6cb..d3482878 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java @@ -37,6 +37,7 @@ import org.floens.chan.ui.adapter.PostsFilter; import org.floens.chan.ui.cell.PostCell; import org.floens.chan.ui.cell.PostCellInterface; import org.floens.chan.ui.cell.ThreadStatusCell; +import org.floens.chan.ui.toolbar.Toolbar; import org.floens.chan.ui.view.ThumbnailView; import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.AnimationUtils; @@ -59,12 +60,15 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL private RecyclerView.LayoutManager layoutManager; private PostAdapter postAdapter; private ChanThread showingThread; - private ThreadListLayoutCallback callback; - private ReplyLayoutStateCallback replyLayoutStateCallback; + private ThreadListLayoutPresenterCallback callback; + private ThreadListLayoutCallback threadListLayoutCallback; private boolean replyOpen; private PostCellInterface.PostViewMode postViewMode; private int spanCount = 2; private int background; + private int toolbarSpacing; + private Toolbar toolbar; + private boolean searchOpen; public ThreadListLayout(Context context, AttributeSet attrs) { super(context, attrs); @@ -84,10 +88,10 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL } public void setCallbacks(PostAdapter.PostAdapterCallback postAdapterCallback, PostCell.PostCellCallback postCellCallback, - ThreadStatusCell.Callback statusCellCallback, ThreadListLayoutCallback callback, - ReplyLayoutStateCallback replyLayoutStateCallback) { + ThreadStatusCell.Callback statusCellCallback, ThreadListLayoutPresenterCallback callback, + ThreadListLayoutCallback threadListLayoutCallback) { this.callback = callback; - this.replyLayoutStateCallback = replyLayoutStateCallback; + this.threadListLayoutCallback = threadListLayoutCallback; postAdapter = new PostAdapter(recyclerView, postAdapterCallback, postCellCallback, statusCellCallback); recyclerView.setAdapter(postAdapter); @@ -96,17 +100,21 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL public void onScrolled(RecyclerView recyclerView, int dx, int dy) { // onScrolled can be called after cleanup() if (showingThread != null) { - switch (postViewMode) { - case LIST: - showingThread.loadable.listViewIndex = Math.max(0, getTopAdapterPosition()); - break; - case CARD: - showingThread.loadable.listViewIndex = Math.max(0, getTopAdapterPosition()); - break; - } + int index = Math.max(0, getTopAdapterPosition()); + int top = recyclerView.getLayoutManager().getChildAt(0).getTop(); + showingThread.loadable.listViewIndex = index; +// showingThread.loadable.listViewTop = top; } } }); + + toolbar = threadListLayoutCallback.getToolbar(); + attachToolbarScroll(true); + + int toolbarHeight = toolbar.getToolbarHeight(); + reply.setPadding(0, toolbarHeight, 0, 0); + searchStatus.setPadding(searchStatus.getPaddingLeft(), searchStatus.getPaddingTop() + toolbarHeight, + searchStatus.getPaddingRight(), searchStatus.getPaddingBottom()); } @Override @@ -132,10 +140,11 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL layoutManager = null; + int toolbarHeight = toolbar.getToolbarHeight(); switch (postViewMode) { case LIST: LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); - recyclerView.setPadding(0, 0, 0, 0); + recyclerView.setPadding(0, toolbarHeight, 0, 0); recyclerView.setLayoutManager(linearLayoutManager); layoutManager = linearLayoutManager; @@ -148,7 +157,7 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL case CARD: GridLayoutManager gridLayoutManager = new GridLayoutManager(null, spanCount, GridLayoutManager.VERTICAL, false); // The cards have a 4dp padding, this way there is always 8dp between the edges - recyclerView.setPadding(dp(4), dp(4), dp(4), dp(4)); + recyclerView.setPadding(dp(4), dp(4) + toolbarHeight, dp(4), dp(4)); recyclerView.setLayoutManager(gridLayoutManager); layoutManager = gridLayoutManager; @@ -177,10 +186,10 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL switch (postViewMode) { case LIST: - ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(thread.loadable.listViewIndex, 0); + ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(thread.loadable.listViewIndex, thread.loadable.listViewTop); break; case CARD: - ((GridLayoutManager) layoutManager).scrollToPositionWithOffset(thread.loadable.listViewIndex, 0); + ((GridLayoutManager) layoutManager).scrollToPositionWithOffset(thread.loadable.listViewIndex, thread.loadable.listViewTop); break; } } else { @@ -220,7 +229,9 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL } else { AndroidUtils.hideKeyboard(reply); } - replyLayoutStateCallback.replyLayoutOpen(open); + threadListLayoutCallback.replyLayoutOpen(open); + + attachToolbarScroll(!(open || searchOpen)); } } @@ -233,10 +244,15 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL } public void showSearch(boolean show) { - AnimationUtils.animateHeight(searchStatus, show); + if (searchOpen != show) { + searchOpen = show; + AnimationUtils.animateHeight(searchStatus, show); - if (show) { - searchStatus.setText(R.string.search_empty); + if (show) { + searchStatus.setText(R.string.search_empty); + } + + attachToolbarScroll(!(show || replyOpen)); } } @@ -261,17 +277,18 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL return true; } + int toolbarHeight = toolbar.getToolbarHeight(); switch (postViewMode) { case LIST: if (getTopAdapterPosition() == 0) { View top = layoutManager.findViewByPosition(0); - return top.getTop() != 0; + return top.getTop() != toolbarHeight; } break; case CARD: if (getTopAdapterPosition() == 0) { View top = layoutManager.findViewByPosition(0); - return top.getTop() != dp(8); // 4dp for the cards, 4dp for this layout + return top.getTop() != dp(8) + toolbarHeight; // 4dp for the cards, 4dp for this layout } break; } @@ -383,6 +400,15 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL callback.requestNewPostLoad(); } + private void attachToolbarScroll(boolean attach) { + if (attach) { + toolbar.attachRecyclerViewScrollStateListener(recyclerView); + } else { + toolbar.detachRecyclerViewScrollStateListener(recyclerView); + toolbar.setCollapse(Toolbar.TOOLBAR_COLLAPSE_SHOW, true); + } + } + private int getTopAdapterPosition() { switch (postViewMode) { case LIST: @@ -393,13 +419,25 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL return -1; } - public interface ThreadListLayoutCallback { + private int getCompleteTopAdapterPosition() { + switch (postViewMode) { + case LIST: + return ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition(); + case CARD: + return ((GridLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition(); + } + return -1; + } + + public interface ThreadListLayoutPresenterCallback { void showThread(Loadable loadable); void requestNewPostLoad(); } - public interface ReplyLayoutStateCallback { + public interface ThreadListLayoutCallback { void replyLayoutOpen(boolean open); + + Toolbar getToolbar(); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java index ae37b7b0..842cded1 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java @@ -36,6 +36,7 @@ public class NavigationItem { public FloatingMenu middleMenu; public View rightView; public boolean hasDrawer = false; + public boolean collapseToolbar = false; boolean search = false; String searchText; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java index eeafd25e..24676df7 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java @@ -26,6 +26,7 @@ import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Build; +import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.util.AttributeSet; import android.view.Gravity; @@ -53,6 +54,29 @@ import static org.floens.chan.utils.AndroidUtils.getAttrColor; import static org.floens.chan.utils.AndroidUtils.setRoundItemBackground; public class Toolbar extends LinearLayout implements View.OnClickListener, LoadView.Listener { + public static final int TOOLBAR_COLLAPSE_HIDE = 1000000; + public static final int TOOLBAR_COLLAPSE_SHOW = -1000000; + + private final RecyclerView.OnScrollListener recyclerViewOnScrollListener = new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + processScrollCollapse(dy); + } + + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + View positionZero = recyclerView.getLayoutManager().findViewByPosition(0); + boolean allowHide = positionZero == null || positionZero.getTop() < 0; + if (allowHide || lastScrollDeltaOffset <= 0) { + setCollapse(lastScrollDeltaOffset <= 0 ? TOOLBAR_COLLAPSE_SHOW : TOOLBAR_COLLAPSE_HIDE, true); + } else { + setCollapse(TOOLBAR_COLLAPSE_SHOW, true); + } + } + } + }; + private ImageView arrowMenuView; private ArrowMenuDrawable arrowMenuDrawable; @@ -61,6 +85,8 @@ public class Toolbar extends LinearLayout implements View.OnClickListener, LoadV private ToolbarCallback callback; private NavigationItem navigationItem; private boolean openKeyboardAfterSearchViewCreated = false; + private int lastScrollDeltaOffset; + private int scrollOffset; public Toolbar(Context context) { super(context); @@ -77,6 +103,39 @@ public class Toolbar extends LinearLayout implements View.OnClickListener, LoadV init(); } + public int getToolbarHeight() { + return getHeight() == 0 ? getLayoutParams().height : getHeight(); + } + + public void processScrollCollapse(int offset) { + processScrollCollapse(offset, false); + } + + public void processScrollCollapse(int offset, boolean animated) { + lastScrollDeltaOffset = offset; + setCollapse(offset, animated); + } + + public void setCollapse(int offset, boolean animated) { + scrollOffset += offset; + scrollOffset = Math.max(0, Math.min(getHeight(), scrollOffset)); + + if (animated) { + animate().translationY(-scrollOffset).setDuration(300).setInterpolator(new DecelerateInterpolator(2f)).start(); + } else { + animate().cancel(); + setTranslationY(-scrollOffset); + } + } + + public void attachRecyclerViewScrollStateListener(RecyclerView recyclerView) { + recyclerView.addOnScrollListener(recyclerViewOnScrollListener); + } + + public void detachRecyclerViewScrollStateListener(RecyclerView recyclerView) { + recyclerView.removeOnScrollListener(recyclerViewOnScrollListener); + } + public void updateNavigation() { closeSearchInternal(); setNavigationItem(false, false, navigationItem); diff --git a/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java b/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java index 432334f4..79d3b3bb 100644 --- a/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java +++ b/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java @@ -104,6 +104,7 @@ public class AndroidUtils { * Tries to open an app that can open the specified URL.
* If this app will open the link then show a chooser to the user without this app.
* Else allow the default logic to run with startActivity. + * * @param link url to open */ public static void openLink(String link) { @@ -173,6 +174,10 @@ public class AndroidUtils { return drawable; } + public static int getDimen(Context context, int dimen) { + return context.getResources().getDimensionPixelSize(dimen); + } + public static int dp(float dp) { return (int) (dp * getRes().getDisplayMetrics().density); } diff --git a/Clover/app/src/main/res/layout/controller_navigation_drawer.xml b/Clover/app/src/main/res/layout/controller_navigation_drawer.xml index e5ec044a..a7acf10e 100644 --- a/Clover/app/src/main/res/layout/controller_navigation_drawer.xml +++ b/Clover/app/src/main/res/layout/controller_navigation_drawer.xml @@ -21,12 +21,11 @@ along with this program. If not, see . android:layout_width="match_parent" android:layout_height="match_parent"> - + android:background="?backcolor"> . + android:layout_height="match_parent" /> - + . --> - + android:layout_height="match_parent"> . + android:layout_height="match_parent" /> - +