Mobile App Dev 2022W: Tutorial 9: Difference between revisions
Created page with "==Code== ===[https://homeostasis.scs.carleton.ca/~soma/mad-2022w/code/PicViewer2/MainActivity.kt MainActivity.kt]=== <syntaxhighlight lang="kotlin" line> package carleton.comp1601.remotepicview2 import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.view.MotionEvent import android.view.View import android.widget.EditText import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity class MainActivity : A..." |
|||
Line 4: | Line 4: | ||
<syntaxhighlight lang="kotlin" line> | <syntaxhighlight lang="kotlin" line> | ||
package carleton.comp1601. | package carleton.comp1601.picviewer2 | ||
import android.os.Bundle | import android.os.Bundle |
Revision as of 17:41, 22 March 2022
Code
MainActivity.kt
package carleton.comp1601.picviewer2
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.MotionEvent
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
private lateinit var p: ImageView
private var pic = R.drawable.kittens
private lateinit var X: PicParamWatcher
private lateinit var Y: PicParamWatcher
private lateinit var scale: PicParamWatcher
private lateinit var r: PicParamWatcher
private lateinit var dragV: dragView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState != null) {
// do something
}
p = findViewById(R.id.mypic)
dragV = dragView(p, ::update, ::toggleImage)
X = PicParamWatcher(0F, findViewById(R.id.x), ::update)
Y = PicParamWatcher(0F, findViewById(R.id.y), ::update)
scale = PicParamWatcher(1F, findViewById(R.id.scale), ::update)
r = PicParamWatcher(0F, findViewById(R.id.rotation), ::update)
update()
}
fun update() {
p.setImageResource(pic)
if (dragV.picDragged) {
dragV.picDragged = false
X.value = p.x
X.refresh()
Y.value = p.y
Y.refresh()
} else {
p.setX(X.value)
p.setY(Y.value)
}
p.setRotation(r.value)
p.setScaleX(scale.value)
p.setScaleY(scale.value)
}
fun toggleImage() {
if (pic == R.drawable.roshi) {
pic = R.drawable.kittens
} else {
pic = R.drawable.roshi
}
update()
}
}
class dragView: View.OnTouchListener {
var dv: View
var update: () -> Unit
var picDragged = false
var lastWasDown = false
var clickHandler: () -> Unit
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
if (event == null || v == null) {
return false
}
val action = event.getAction()
val x = event.rawX
val y = event.rawY
var screenLoc = IntArray(2)
dv.getLocationOnScreen(screenLoc)
val Xoffset = screenLoc[0] - dv.x
val Yoffset = screenLoc[1] - dv.y
if (action == MotionEvent.ACTION_MOVE) {
lastWasDown = false
dv.x = x - (dv.width/2 + Xoffset)
dv.y = y - (dv.height/2 + Yoffset)
picDragged = true
update()
} else if (action == MotionEvent.ACTION_DOWN) {
lastWasDown = true
} else if (action == MotionEvent.ACTION_UP) {
if (lastWasDown) {
lastWasDown = false
clickHandler()
}
}
return true
}
constructor(v: View, u: () -> Unit, ch: () -> Unit) {
dv = v
dv.setOnTouchListener(this)
update = u
clickHandler = ch
}
}
class PicParamWatcher: TextWatcher {
var update: () -> Unit
var widget: EditText
var defaultValue: Float
var value: Float
var valueChanged = false
override fun afterTextChanged(s: Editable) {
if (valueChanged) {
valueChanged = false
return
}
val new_value = s.toString().toFloatOrNull()
if (new_value != null) {
value = new_value
} else {
value = defaultValue
}
update()
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
fun refresh() {
valueChanged = true
widget.setText(value.toString())
}
constructor(x: Float, w: EditText, u: () -> Unit) {
update = u
widget = w
defaultValue = x
value = x
w.addTextChangedListener(this)
refresh()
}
}
activity_main.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/mypic"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toTopOf="@+id/rotation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<EditText
android:id="@+id/rotation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="5"
android:inputType="number"
app:layout_constraintBottom_toTopOf="@+id/scale"
app:layout_constraintStart_toStartOf="@+id/scale" />
<EditText
android:id="@+id/scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="5"
android:inputType="numberDecimal"
app:layout_constraintBottom_toTopOf="@+id/x"
app:layout_constraintStart_toStartOf="@+id/x" />
<EditText
android:id="@+id/x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="5"
android:inputType="numberSigned"
app:layout_constraintBottom_toTopOf="@+id/y"
app:layout_constraintStart_toStartOf="@+id/y" />
<EditText
android:id="@+id/y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:ems="5"
android:inputType="numberSigned"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/ylabel" />
<TextView
android:id="@+id/rotationlabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:text="rotation"
android:textStyle="bold"
app:layout_constraintBaseline_toBaselineOf="@+id/rotation"
app:layout_constraintEnd_toStartOf="@+id/rotation"
/>
<TextView
android:id="@+id/scalelabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:layout_marginBottom="11dp"
android:text="scale"
android:textStyle="bold"
app:layout_constraintBaseline_toBaselineOf="@+id/scale"
app:layout_constraintEnd_toStartOf="@+id/scale" />
<TextView
android:id="@+id/xlabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:text="X"
android:textStyle="bold"
app:layout_constraintBaseline_toBaselineOf="@+id/x"
app:layout_constraintEnd_toStartOf="@+id/x" />
<TextView
android:id="@+id/ylabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:text="Y"
android:textStyle="bold"
app:layout_constraintBaseline_toBaselineOf="@+id/y"
app:layout_constraintEnd_toStartOf="@+id/y" />
</androidx.constraintlayout.widget.ConstraintLayout>