Last active
November 11, 2020 16:12
-
-
Save gchumillas/1027794c476f7f4eeddc6bfa53a17e84 to your computer and use it in GitHub Desktop.
Rotate, Scale and Move in Android (Kotlin)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.myapplication | |
import android.annotation.SuppressLint | |
import android.app.Activity | |
import android.graphics.Matrix | |
import android.graphics.PointF | |
import android.os.Bundle | |
import android.view.ScaleGestureDetector | |
import androidx.core.view.doOnLayout | |
import com.almeros.android.multitouch.MoveGestureDetector | |
import com.almeros.android.multitouch.RotateGestureDetector | |
import com.example.myapplication.databinding.ActivityMainBinding | |
@SuppressLint("ClickableViewAccessibility") | |
class MainActivity : Activity() { | |
private lateinit var binding: ActivityMainBinding | |
private lateinit var imageMatrix: Matrix | |
private var translate = PointF(0f, 0f) | |
private var rotate = 0f | |
private var scale = 1f | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
binding = ActivityMainBinding.inflate(layoutInflater) | |
setContentView(binding.root) | |
val imageView = binding.imageView | |
imageView.doOnLayout { | |
var moveGestureDetector = MoveGestureDetector(this, MoveGestureHandler()) | |
var rotateGestureDetector = RotateGestureDetector(this, RotateGestureHandler()) | |
val scaleGestureDetector = ScaleGestureDetector(this, ScaleGestureHandler()) | |
val center = PointF( | |
imageView.measuredWidth.toFloat() / 2f, | |
imageView.measuredHeight.toFloat() / 2f | |
) | |
// Centers the image | |
imageMatrix = Matrix().apply { | |
setTranslate( | |
center.x - imageView.drawable.intrinsicWidth / 2f, | |
center.y - imageView.drawable.intrinsicHeight / 2f | |
) | |
} | |
imageView.imageMatrix = imageMatrix | |
imageView.setOnTouchListener { _, event -> | |
moveGestureDetector.onTouchEvent(event) | |
rotateGestureDetector.onTouchEvent(event) | |
scaleGestureDetector.onTouchEvent(event) | |
imageView.imageMatrix = Matrix().apply { | |
set(imageMatrix) | |
postTranslate(-center.x, -center.y) | |
postRotate(rotate) | |
postScale(scale, scale) | |
postTranslate(center.x + translate.x, center.y + translate.y) | |
} | |
true | |
} | |
} | |
} | |
inner class MoveGestureHandler : MoveGestureDetector.SimpleOnMoveGestureListener() { | |
override fun onMove(detector: MoveGestureDetector): Boolean { | |
translate = detector.focusDelta | |
return super.onMove(detector) | |
} | |
override fun onMoveEnd(detector: MoveGestureDetector) { | |
imageMatrix = Matrix(binding.imageView.imageMatrix) | |
translate = PointF(0f, 0f) | |
super.onMoveEnd(detector) | |
} | |
} | |
inner class RotateGestureHandler : RotateGestureDetector.SimpleOnRotateGestureListener() { | |
override fun onRotate(detector: RotateGestureDetector): Boolean { | |
rotate = -detector.rotationDegreesDelta | |
return super.onRotate(detector) | |
} | |
override fun onRotateEnd(detector: RotateGestureDetector?) { | |
imageMatrix = Matrix(binding.imageView.imageMatrix) | |
rotate = 0f | |
super.onRotateEnd(detector) | |
} | |
} | |
inner class ScaleGestureHandler : ScaleGestureDetector.SimpleOnScaleGestureListener() { | |
override fun onScale(detector: ScaleGestureDetector): Boolean { | |
scale = detector.scaleFactor | |
return super.onScale(detector) | |
} | |
override fun onScaleEnd(detector: ScaleGestureDetector?) { | |
imageMatrix = Matrix(binding.imageView.imageMatrix) | |
scale = 1f | |
super.onScaleEnd(detector) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="vertical" | |
tools:context=".MainActivity"> | |
<ImageView | |
android:id="@+id/imageView" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_gravity="center" | |
android:contentDescription="@string/image_editor" | |
android:scaleType="matrix" | |
android:src="@mipmap/ic_launcher" /> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apply plugin: 'com.android.application' | |
apply plugin: 'kotlin-android' | |
apply plugin: 'kotlin-android-extensions' | |
android { | |
compileSdkVersion 29 | |
buildToolsVersion "29.0.2" | |
defaultConfig { | |
applicationId "com.example.myapplication" | |
minSdkVersion 19 | |
targetSdkVersion 29 | |
versionCode 1 | |
versionName "1.0" | |
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | |
} | |
buildTypes { | |
release { | |
minifyEnabled false | |
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | |
} | |
} | |
viewBinding { | |
enabled = true | |
} | |
compileOptions { | |
sourceCompatibility JavaVersion.VERSION_1_8 | |
targetCompatibility JavaVersion.VERSION_1_8 | |
} | |
kotlinOptions { | |
jvmTarget = JavaVersion.VERSION_1_8.toString() | |
} | |
} | |
dependencies { | |
implementation fileTree(dir: 'libs', include: ['*.jar']) | |
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | |
implementation 'androidx.appcompat:appcompat:1.1.0' | |
implementation 'androidx.core:core-ktx:1.2.0' | |
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | |
testImplementation 'junit:junit:4.13' | |
androidTestImplementation 'androidx.test.ext:junit:1.1.1' | |
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' | |
implementation 'com.github.Almeros:android-gesture-detectors:v1.0.1' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment