X-Git-Url: https://git.ktnx.net/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fui%2FFabManager.java;h=bbacc3e4c0cff52a7d922bb92eb8ea92b4032aef;hb=HEAD;hp=249c5d844352945a02d40396ed47486f5a97f59d;hpb=abc2cfe2c435d10ade2533d09eccab9a32f5bba6;p=mobile-ledger.git diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/FabManager.java b/app/src/main/java/net/ktnx/mobileledger/ui/FabManager.java index 249c5d84..bbacc3e4 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/FabManager.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/FabManager.java @@ -22,6 +22,8 @@ import android.animation.AnimatorListenerAdapter; import android.animation.TimeInterpolator; import android.annotation.SuppressLint; import android.content.Context; +import android.os.Handler; +import android.os.Looper; import android.view.MotionEvent; import android.view.ViewGroup; import android.view.ViewPropertyAnimator; @@ -37,6 +39,7 @@ import net.ktnx.mobileledger.utils.Logger; public class FabManager { private static final boolean FAB_SHOWN = true; private static final boolean FAB_HIDDEN = false; + private static final int AUTO_SHOW_DELAY_MILLS = 4000; private final FloatingActionButton fab; private boolean wantedFabState = FAB_SHOWN; private ViewPropertyAnimator fabSlideAnimator; @@ -44,58 +47,8 @@ public class FabManager { public FabManager(FloatingActionButton fab) { this.fab = fab; } - @SuppressLint("ClickableViewAccessibility") - public static void handle(FabHandler activity, RecyclerView recyclerView) { - final float triggerAbsolutePixels = DimensionUtils.dp2px(activity.getContext(), 20f); - final float triggerRelativePixels = triggerAbsolutePixels / 4f; - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - Logger.debug("touch", "Scrolled " + dy); - if (dy <= 0) - activity.showManagedFab(); - else - activity.hideManagedFab(); - - super.onScrolled(recyclerView, dx, dy); - } - }); - recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() { - private float absoluteAnchor = -1; - @Override - public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { - switch (e.getActionMasked()) { - case MotionEvent.ACTION_DOWN: - absoluteAnchor = e.getRawY(); -// Logger.debug("touch", -// String.format(Locale.US, "Touch down at %4.2f", absoluteAnchor)); - break; - case MotionEvent.ACTION_MOVE: - if (absoluteAnchor < 0) - break; - - final float absoluteY = e.getRawY(); -// Logger.debug("touch", String.format(Locale.US, "Move to %4.2f", -// absoluteY)); - - if (absoluteY > absoluteAnchor + triggerAbsolutePixels) { - // swipe down -// Logger.debug("touch", "SHOW"); - activity.showManagedFab(); - absoluteAnchor = absoluteY; - } - else if (absoluteY < absoluteAnchor - triggerAbsolutePixels) { - // swipe up -// Logger.debug("touch", "HIDE"); - activity.hideManagedFab(); - absoluteAnchor = absoluteY; - } - - break; - } - return false; - } - }); + public static void handle(FabHandler fabHandler, RecyclerView recyclerView) { + new ScrollFabHandler(fabHandler, recyclerView); } private void slideFabTo(int target, long duration, TimeInterpolator interpolator) { fabSlideAnimator = fab.animate() @@ -109,8 +62,10 @@ public class FabManager { }); } public void showFab() { - if (wantedFabState == FAB_SHOWN) + if (wantedFabState == FAB_SHOWN) { +// Logger.debug("fab", "Ignoring request to show already visible FAB"); return; + } // b.btnAddTransaction.show(); if (this.fabSlideAnimator != null) { @@ -118,13 +73,16 @@ public class FabManager { fab.clearAnimation(); } + Logger.debug("fab", "Showing FAB"); wantedFabState = FAB_SHOWN; slideFabTo(0, 200L, com.google.android.material.animation.AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR); } public void hideFab() { - if (wantedFabState == FAB_HIDDEN) + if (wantedFabState == FAB_HIDDEN) { +// Logger.debug("fab", "Ignoring request to hide FAB -- already hidden"); return; + } calcVerticalFabOffset(); @@ -134,6 +92,7 @@ public class FabManager { fab.clearAnimation(); } + Logger.debug("fab", "Hiding FAB"); wantedFabState = FAB_HIDDEN; slideFabTo(fabVerticalOffset, 150L, com.google.android.material.animation.AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR); @@ -163,4 +122,80 @@ public class FabManager { void hideManagedFab(); } + + public static class ScrollFabHandler { + final private FabHandler fabHandler; + private int generation = 0; + @SuppressLint("ClickableViewAccessibility") + ScrollFabHandler(FabHandler fabHandler, RecyclerView recyclerView) { + this.fabHandler = fabHandler; + final float triggerAbsolutePixels = DimensionUtils.dp2px(fabHandler.getContext(), 20f); + final float triggerRelativePixels = triggerAbsolutePixels / 4f; + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { +// Logger.debug("touch", "Scrolled " + dy); + if (dy <= 0) { + showFab(); + } + else + hideFab(); + + super.onScrolled(recyclerView, dx, dy); + } + }); + recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() { + private float absoluteAnchor = -1; + @Override + public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, + @NonNull MotionEvent e) { + switch (e.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + absoluteAnchor = e.getRawY(); +// Logger.debug("touch", +// String.format(Locale.US, "Touch down at %4.2f", absoluteAnchor)); + break; + case MotionEvent.ACTION_MOVE: + if (absoluteAnchor < 0) + break; + + final float absoluteY = e.getRawY(); +// Logger.debug("touch", String.format(Locale.US, "Move to %4.2f", +// absoluteY)); + + if (absoluteY > absoluteAnchor + triggerAbsolutePixels) { + // swipe down +// Logger.debug("touch", "SHOW"); + showFab(); + absoluteAnchor = absoluteY; + } + else if (absoluteY < absoluteAnchor - triggerAbsolutePixels) { + // swipe up +// Logger.debug("touch", "HIDE"); + hideFab(); + absoluteAnchor = absoluteY; + } + + break; + } + return false; + } + }); + } + private void hideFab() { + generation++; + int thisGeneration = generation; + fabHandler.hideManagedFab(); + new Handler(Looper.getMainLooper()).postDelayed(() -> { + if (generation != thisGeneration) + return; + + showFab(); + }, AUTO_SHOW_DELAY_MILLS); + } + private void showFab() { + generation++; + fabHandler.showManagedFab(); + } + } }