Skip to content

Commit

Permalink
Add extensions function to apply draggable behaviour to any View
Browse files Browse the repository at this point in the history
  • Loading branch information
hyuwah committed Sep 20, 2019
1 parent 9ada6f1 commit e577c9d
Show file tree
Hide file tree
Showing 6 changed files with 307 additions and 56 deletions.
134 changes: 109 additions & 25 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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() {

Expand All @@ -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 {
Expand All @@ -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)
}
}
Loading

0 comments on commit e577c9d

Please sign in to comment.