From e577c9dd4553e08161420bfc9292a79c230b2534 Mon Sep 17 00:00:00 2001 From: Muhammad Wahyudin Date: Fri, 20 Sep 2019 09:08:09 +0700 Subject: [PATCH] Add extensions function to apply draggable behaviour to any View --- .idea/codeStyles/Project.xml | 134 ++++++++++++++---- .../hyuwah/draggableviewlib/Constants.kt | 13 ++ .../draggableviewlib/DraggableImageView.kt | 3 +- .../hyuwah/draggableviewlib/Extensions.kt | 111 +++++++++++++++ .../hyuwah/draggableview/MainActivity.kt | 16 ++- example/src/main/res/layout/activity_main.xml | 86 +++++++---- 6 files changed, 307 insertions(+), 56 deletions(-) create mode 100644 draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/Constants.kt create mode 100644 draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/Extensions.kt diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index a9ea262..9624886 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -6,31 +6,115 @@ - - - - - - - - - - + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
diff --git a/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/Constants.kt b/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/Constants.kt new file mode 100644 index 0000000..1df7921 --- /dev/null +++ b/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/Constants.kt @@ -0,0 +1,13 @@ +package io.github.hyuwah.draggableviewlib + +object Constants { + + enum class STICKY { + NONE, + AXIS_X, + AXIS_Y, + AXIS_XY + } + + const val DRAG_TOLERANCE = 16 +} \ No newline at end of file diff --git a/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/DraggableImageView.kt b/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/DraggableImageView.kt index 88c5c2b..c05b736 100644 --- a/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/DraggableImageView.kt +++ b/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/DraggableImageView.kt @@ -5,6 +5,7 @@ import android.util.AttributeSet import android.view.MotionEvent import android.view.View import android.widget.ImageView +import io.github.hyuwah.draggableviewlib.Constants.DRAG_TOLERANCE import kotlin.math.abs /** @@ -20,8 +21,6 @@ class DraggableImageView(context: Context, attrs: AttributeSet) : ImageView(cont const val STICKY_AXIS_XY = 3 } - private var DRAG_TOLERANCE = 16 - // Attributes private var stickyAxis: Int private var mAnimate: Boolean diff --git a/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/Extensions.kt b/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/Extensions.kt new file mode 100644 index 0000000..2935317 --- /dev/null +++ b/draggableviewlib/src/main/java/io/github/hyuwah/draggableviewlib/Extensions.kt @@ -0,0 +1,111 @@ +package io.github.hyuwah.draggableviewlib + +import android.view.MotionEvent +import android.view.View +import io.github.hyuwah.draggableviewlib.Constants.DRAG_TOLERANCE +import java.lang.Math.max +import kotlin.math.abs +import kotlin.math.min + +fun View.makeDraggable( + stickyAxis: Constants.STICKY = Constants.STICKY.NONE, + animated: Boolean = true +) { + var widgetInitialX = 0f + var widgetDX = 0f + var widgetInitialY = 0f + var widgetDY = 0f + setOnTouchListener { v, event -> + val viewParent = v.parent as View + val PARENT_HEIGHT = viewParent.height + val PARENT_WIDTH = viewParent.width + + when (event.actionMasked) { + MotionEvent.ACTION_DOWN -> { + widgetDX = v.x - event.rawX + widgetDY = v.y - event.rawY + widgetInitialX = v.x + widgetInitialY = v.y + } + MotionEvent.ACTION_MOVE -> { + var newX = event.rawX + widgetDX + newX = max(0F, newX) + newX = min((PARENT_WIDTH - v.width).toFloat(), newX) + v.x = newX + + var newY = event.rawY + widgetDY + newY = max(0F, newY) + newY = min((PARENT_HEIGHT - v.height).toFloat(), newY) + v.y = newY + } + MotionEvent.ACTION_UP -> { + when (stickyAxis) { + Constants.STICKY.AXIS_X -> { + if (event.rawX >= PARENT_WIDTH / 2) { + if (animated) + v.animate().x((PARENT_WIDTH) - (v.width).toFloat()).setDuration(250).start() + else + v.x = (PARENT_WIDTH) - (v.width).toFloat() + } else { + if (animated) + v.animate().x(0F).setDuration(250).start() + else + v.x = 0F + } + } + Constants.STICKY.AXIS_Y -> { + if (event.rawY >= PARENT_HEIGHT / 2) { + if (animated) + v.animate().y((PARENT_HEIGHT) - (v.height).toFloat()).setDuration( + 250 + ).start() + else + v.y = (PARENT_HEIGHT) - (v.height).toFloat() + } else { + if (animated) + v.animate().y(0F).setDuration(250).start() + else { + if (animated) + v.animate().y(0F).setDuration(250).start() + else + v.y = 0F + } + } + } + Constants.STICKY.AXIS_XY -> { + if (event.rawX >= PARENT_WIDTH / 2) { + if (animated) + v.animate().x((PARENT_WIDTH) - (v.width).toFloat()).setDuration(250).start() + else + v.x = (PARENT_WIDTH) - (v.width).toFloat() + } else { + if (animated) + v.animate().x(0F).setDuration(250).start() + v.x = 0F + } + + if (event.rawY >= PARENT_HEIGHT / 2) { + if (animated) + v.animate().y((PARENT_HEIGHT) - (v.height).toFloat()).setDuration( + 250 + ).start() + else + v.y = (PARENT_HEIGHT) - (v.height).toFloat() + } else { + if (animated) + v.animate().y(0F).setDuration(250).start() + else + v.y = 0F + } + } + } + + if (abs(v.x - widgetInitialX) <= DRAG_TOLERANCE && abs(v.y - widgetInitialY) <= DRAG_TOLERANCE) { + performClick() + } + } + else -> return@setOnTouchListener false + } + true + } +} \ No newline at end of file diff --git a/example/src/main/java/io/github/hyuwah/draggableview/MainActivity.kt b/example/src/main/java/io/github/hyuwah/draggableview/MainActivity.kt index de8b28f..f8b0ca3 100644 --- a/example/src/main/java/io/github/hyuwah/draggableview/MainActivity.kt +++ b/example/src/main/java/io/github/hyuwah/draggableview/MainActivity.kt @@ -1,11 +1,14 @@ package io.github.hyuwah.draggableview -import android.support.v7.app.AppCompatActivity import android.os.Bundle +import android.support.v7.app.AppCompatActivity import android.widget.Button import android.widget.Switch import android.widget.Toast +import io.github.hyuwah.draggableviewlib.Constants import io.github.hyuwah.draggableviewlib.DraggableImageView +import io.github.hyuwah.draggableviewlib.makeDraggable +import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { @@ -23,7 +26,13 @@ class MainActivity : AppCompatActivity() { swAnimate.isChecked = dvTest.isAnimate() swAnimate.setOnCheckedChangeListener { _, isChecked -> - if(isChecked) dvTest.setAnimate(true) else dvTest.setAnimate(false) + if (isChecked) { + dvTest.setAnimate(true) + tv_test_draggable.makeDraggable(Constants.STICKY.AXIS_X, true) + } else { + tv_test_draggable.makeDraggable(Constants.STICKY.AXIS_X, false) + dvTest.setAnimate(false) + } } btnStickyX.setOnClickListener { @@ -49,5 +58,8 @@ class MainActivity : AppCompatActivity() { dvTest.setOnClickListener { Toast.makeText(this@MainActivity, "Clicked", Toast.LENGTH_SHORT).show() } + + ll_test_draggable.makeDraggable(Constants.STICKY.AXIS_Y) + tv_test_draggable.makeDraggable(Constants.STICKY.AXIS_X, true) } } diff --git a/example/src/main/res/layout/activity_main.xml b/example/src/main/res/layout/activity_main.xml index 83a27d7..129e1a6 100644 --- a/example/src/main/res/layout/activity_main.xml +++ b/example/src/main/res/layout/activity_main.xml @@ -1,62 +1,94 @@ - - + +