diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MovableFloatingActionButton.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MovableFloatingActionButton.java new file mode 100644 index 00000000..f9d3dcff --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MovableFloatingActionButton.java @@ -0,0 +1,121 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +public class MovableFloatingActionButton extends FloatingActionButton implements View.OnTouchListener { + private final static float CLICK_DRAG_TOLERANCE = 50; + private long downTime = 0; + private boolean moved = false; + private boolean longClicked = false; + + private float downRawX, downRawY; + private float dX, dY; + + public MovableFloatingActionButton(Context context) { + super(context); + init(); + } + + public MovableFloatingActionButton(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public MovableFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + private void init() { + setOnTouchListener(this); + } + + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)view.getLayoutParams(); + + int action = motionEvent.getAction(); + if (action == MotionEvent.ACTION_DOWN) { + downTime = System.currentTimeMillis(); + moved = false; + + downRawX = motionEvent.getRawX(); + downRawY = motionEvent.getRawY(); + dX = view.getX() - downRawX; + dY = view.getY() - downRawY; + + return true; + + } else if (action == MotionEvent.ACTION_MOVE) { + if (!moved) { + if (System.currentTimeMillis() - downTime >= 300) { + if (!longClicked) { + longClicked = true; + return performLongClick(); + } else { + moved = true; + } + } + float upRawX = motionEvent.getRawX(); + float upRawY = motionEvent.getRawY(); + + float upDX = upRawX - downRawX; + float upDY = upRawY - downRawY; + + if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { + return true; + } else { + moved = true; + } + } + + int viewWidth = view.getWidth(); + int viewHeight = view.getHeight(); + + View viewParent = (View)view.getParent(); + int parentWidth = viewParent.getWidth(); + int parentHeight = viewParent.getHeight(); + + float newX = motionEvent.getRawX() + dX; + newX = Math.max(layoutParams.leftMargin, newX); // Don't allow the FAB past the left hand side of the parent + newX = Math.min(parentWidth - viewWidth - layoutParams.rightMargin, newX); // Don't allow the FAB past the right hand side of the parent + + float newY = motionEvent.getRawY() + dY; + newY = Math.max(layoutParams.topMargin, newY); // Don't allow the FAB past the top of the parent + newY = Math.min(parentHeight - viewHeight - layoutParams.bottomMargin, newY); // Don't allow the FAB past the bottom of the parent + + view.animate() + .x(newX) + .y(newY) + .setDuration(0) + .start(); + + return true; + } else if (action == MotionEvent.ACTION_UP) { + if (longClicked) { + longClicked = false; + return true; + } + + float upRawX = motionEvent.getRawX(); + float upRawY = motionEvent.getRawY(); + + float upDX = upRawX - downRawX; + float upDY = upRawY - downRawY; + + if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { + return System.currentTimeMillis() - downTime >= 300 ? performLongClick() : performClick(); + } else { + return true; + } + } else { + return super.onTouchEvent(motionEvent); + } + } +} diff --git a/app/src/main/res/layout/activity_view_post_detail.xml b/app/src/main/res/layout/activity_view_post_detail.xml index 6fd17685..4f32b0e8 100644 --- a/app/src/main/res/layout/activity_view_post_detail.xml +++ b/app/src/main/res/layout/activity_view_post_detail.xml @@ -39,7 +39,7 @@ android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> -