Skip to content

Instantly share code, notes, and snippets.

@ceosilvajr
Last active October 31, 2019 11:19
Show Gist options
  • Save ceosilvajr/ecd370046a638c36f3f611e5ec3a5166 to your computer and use it in GitHub Desktop.
Save ceosilvajr/ecd370046a638c36f3f611e5ec3a5166 to your computer and use it in GitHub Desktop.
Give you fab a movable experience
class MovableFabButton : FloatingActionButton, View.OnTouchListener {
private var downRawX: Float = 0.toFloat()
private var downRawY: Float = 0.toFloat()
private var dX: Float = 0.toFloat()
private var dY: Float = 0.toFloat()
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init()
}
private fun init() {
setOnTouchListener(this)
}
override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
val layoutParams = view.layoutParams as ViewGroup.MarginLayoutParams
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
downRawX = motionEvent.rawX
downRawY = motionEvent.rawY
dX = view.x - downRawX
dY = view.y - downRawY
return true
}
MotionEvent.ACTION_MOVE -> {
val viewWidth = view.width
val viewHeight = view.height
val viewParent = view.parent as View
val parentWidth = viewParent.width
val parentHeight = viewParent.height
var newX = motionEvent.rawX + dX
newX = layoutParams.leftMargin.toFloat().coerceAtLeast(newX)
newX = (parentWidth - viewWidth - layoutParams.rightMargin).toFloat().coerceAtMost(newX)
var newY = motionEvent.rawY + dY
newY = layoutParams.topMargin.toFloat().coerceAtLeast(newY)
newY = (parentHeight - viewHeight - layoutParams.bottomMargin).toFloat().coerceAtMost(newY)
view.animate().x(newX).y(newY).setDuration(0).start()
return true
}
MotionEvent.ACTION_UP -> {
val upRawX = motionEvent.rawX
val upRawY = motionEvent.rawY
val upDX = upRawX - downRawX
val upDY = upRawY - downRawY
return if (abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) {
performClick()
} else {
true
}
}
else -> return super.onTouchEvent(motionEvent)
}
}
companion object {
private const val CLICK_DRAG_TOLERANCE = 10f
}
}
<MovableFabButton
android:id="@+id/fab_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_home"
android:tint="@android:color/white" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment