Skip to content

Instantly share code, notes, and snippets.

@mrahimygk
Created August 26, 2021 11:59
Show Gist options
  • Save mrahimygk/df222a27b4e906e130206842a8b64d3c to your computer and use it in GitHub Desktop.
Save mrahimygk/df222a27b4e906e130206842a8b64d3c to your computer and use it in GitHub Desktop.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000">
<View
android:id="@+id/longpress"
android:layout_width="128dp"
android:layout_height="128dp"
android:background="@drawable/redbg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/lockparent"
android:layout_width="wrap_content"
android:scaleY="0"
android:scaleX="0"
android:paddingBottom="148dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@id/longpress"
app:layout_constraintEnd_toEndOf="@id/longpress"
app:layout_constraintStart_toStartOf="@id/longpress">
<androidx.cardview.widget.CardView
android:id="@+id/card"
android:layout_width="32dp"
android:layout_height="64dp"
android:background="@drawable/bg"
app:cardCornerRadius="16dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/oval"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/arrow"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@android:drawable/arrow_up_float" />
<ImageView
android:id="@+id/lock"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="16dp"
android:src="@android:drawable/ic_lock_lock"
app:tint="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:id="@+id/longpressHelper"
android:layout_width="128dp"
android:layout_height="128dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
import android.graphics.Point
import android.os.Parcel
import android.os.Parcelable
import android.util.Size
import java.io.PrintWriter
/**
* Point holds two integer coordinates
*/
class FloatPoint : Parcelable {
var x = 0f
var y = 0f
constructor() {}
constructor(x: Float, y: Float) {
this.x = x
this.y = y
}
constructor(src: FloatPoint) {
x = src.x
y = src.y
}
constructor(src: Point) {
x = src.x.toFloat()
y = src.y.toFloat()
}
/**
* Set the point's x and y coordinates
*/
operator fun set(x: Float, y: Float) {
this.x = x
this.y = y
}
/**
* Negate the point's coordinates
*/
fun negate() {
x = -x
y = -y
}
/**
* Offset the point's coordinates by dx, dy
*/
fun offset(dx: Float, dy: Float) {
x += dx
y += dy
}
/**
* Returns true if the point's coordinates equal (x,y)
*/
fun equals(x: Float, y: Float): Boolean {
return this.x == x && this.y == y
}
override fun hashCode(): Int {
var result = x
result = 31 * result + y
return result.toInt()
}
override fun toString(): String {
return "FloatPoint($x, $y)"
}
/** @hide
*/
fun printShortString(pw: PrintWriter) {
pw.print("[")
pw.print(x)
pw.print(",")
pw.print(y)
pw.print("]")
}
/**
* Parcelable interface methods
*/
override fun describeContents(): Int {
return 0
}
/**
* Write this point to the specified parcel. To restore a point from
* a parcel, use readFromParcel()
* @param out The parcel to write the point's coordinates into
*/
override fun writeToParcel(out: Parcel?, flags: Int) {
out?.writeFloat(x)
out?.writeFloat(y)
}
/**
* Set the point's coordinates from the data stored in the specified
* parcel. To write a point to a parcel, call writeToParcel().
*
* @param in The parcel to read the point's coordinates from
*/
fun readFromParcel(`in`: Parcel) {
x = `in`.readFloat()
y = `in`.readFloat()
}
companion object CREATOR : Parcelable.Creator<FloatPoint> {
/**
* Return a new point from the data in the specified parcel.
*/
override fun createFromParcel(`in`: Parcel): FloatPoint {
val r = FloatPoint()
r.readFromParcel(`in`)
return r
}
/**
* Return an array of rectangles of the specified size.
*/
override fun newArray(size: Int): Array<FloatPoint?> {
return arrayOfNulls(size)
}
/** {@hide} */
fun convert(size: Size): Point {
return Point(size.width, size.height)
}
/** {@hide} */
fun convert(point: FloatPoint): Size {
return Size(point.x.toInt(), point.y.toInt())
}
}
}
import android.animation.ValueAnimator
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.constraintlayout.widget.ConstraintLayout
import kotlin.math.abs
@SuppressWarnings("all")
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val dp = resources.displayMetrics.density
var draggableItem: DraggableItem? = null
val MAX_MOVE = 400f
val MAX_RAD = 64f
val view = findViewById<View>(R.id.longpress)
val parent = findViewById<ViewGroup>(R.id.parent)
view.setOnTouchListener { v: View, motionEvent: MotionEvent ->
if (motionEvent.action == MotionEvent.ACTION_UP || motionEvent.action == MotionEvent.ACTION_POINTER_UP) {
draggableItem?.apply {
val dx = startingPoint.x - motionEvent.x
val dy = startingPoint.y - motionEvent.y
val dragPercentX = abs(dx)
val dragPercentY = abs(dy)
_view.animate().scaleY(0f).scaleX(0f).translationY(startingPoint.y - 200).start()
ValueAnimator.ofFloat(64f * dp, 32f * dp).run {
addUpdateListener { v ->
card.run {
val layoutParams00 = layoutParams
if (dy < -200 && dragPercentY < 100) {
layoutParams00.width = (animatedValue as Float * dp).toInt()
}
layoutParams = layoutParams00
}
/*if (dy < -200 && dragPercentY < 100) {
radius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dPercentY, context.resources.displayMetrics)
}*/
}
start()
}
draggableItem = null
}
}
if (motionEvent.action == MotionEvent.ACTION_DOWN || motionEvent.action == MotionEvent.ACTION_POINTER_DOWN) {
val lockparent = this@MainActivity.findViewById<ViewGroup>(R.id.lockparent)
(0..parent.childCount).forEach {
parent.getChildAt(it).run {
if (this is View && this.id == R.id.longpress) {
draggableItem = DraggableItem(
lockparent,
FloatPoint(motionEvent.x, motionEvent.y),
card = lockparent.findViewById(R.id.card),
arrow = lockparent.findViewById(R.id.arrow),
lock = lockparent.findViewById(R.id.lock),
)
onFoundItem(draggableItem)
}
}
}
}
if (motionEvent.action == MotionEvent.ACTION_MOVE) {
draggableItem?.run {
val dy = motionEvent.y - startingPoint.y
val dragPercentY = findPercentage(abs(dy), MAX_MOVE)
val dPercentY = findPercentage(abs(dy), MAX_RAD)
Log.d("TAG", "dragPercentY: $dragPercentY")
Log.d("TAG", "dy: $dy")
_view.run {
if (dy < -200 && dragPercentY < 100) translationY = dy + 200
}
card.run {
val layoutParams00 = layoutParams
if (dy < -200 && dragPercentY < 100) {
layoutParams00.width = ((64f * dp) * (dragPercentY / 100)).toInt()
}
layoutParams = layoutParams00
if (dy < -200 && dragPercentY < 100) {
radius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dPercentY, context.resources.displayMetrics)
}
}
arrow.run {
var lastPercent = 0f
if (dy < -200) {
lastPercent = dragPercentY
}
Log.d("TAG", "lastPercent: $lastPercent")
if (dy < -200 && dragPercentY < 100) {
alpha = 1f - (dragPercentY / 100)
}
}
lock.run {
val layoutParams00 = layoutParams as ConstraintLayout.LayoutParams
if (dy < -200 && dragPercentY < 100) {
layoutParams00.topMargin = ((16f * dp) * (1 - (dragPercentY / 100))).toInt()
if(dragPercentY> 80){
setImageDrawable(getDrawable(android.R.drawable.ic_delete))
imageTintList = ColorStateList.valueOf(Color.RED)
} else {
setImageDrawable(getDrawable(android.R.drawable.ic_lock_lock))
imageTintList = ColorStateList.valueOf(Color.BLACK)
}
}
layoutParams = layoutParams00
}
}
}
return@setOnTouchListener true
}
}
private fun onFoundItem(draggableItem: DraggableItem?) {
draggableItem?.run { _view.animate().scaleY(1f).scaleX(1f).start() }
}
}
data class DraggableItem(
val _view: View,
val startingPoint: FloatPoint,
val card: CardView,
val arrow: ImageView,
val lock: ImageView
)
fun findPercentage(n: Float, v: Float) = (n * 100.0f) / v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment