Camera icons rotation

This commit is contained in:
Hardcore Sushi 2020-09-04 04:00:19 +02:00
parent 9c31576b97
commit c82d6c0e36
2 changed files with 129 additions and 1 deletions

View File

@ -6,7 +6,11 @@ import android.os.Bundle
import android.text.InputType
import android.view.View
import android.view.WindowManager
import android.view.animation.Animation
import android.view.animation.LinearInterpolator
import android.view.animation.RotateAnimation
import android.widget.EditText
import android.widget.ImageView
import android.widget.Toast
import androidx.core.content.ContextCompat
import com.otaliastudios.cameraview.CameraListener
@ -25,7 +29,7 @@ import java.io.ByteArrayInputStream
import java.text.SimpleDateFormat
import java.util.*
class CameraActivity : BaseActivity() {
class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
companion object {
private val flashModes = listOf(Flash.AUTO, Flash.ON, Flash.OFF)
private val gridTitles = listOf(R.string.grid_none, R.string.grid_3x3, R.string.grid_4x4)
@ -45,6 +49,9 @@ class CameraActivity : BaseActivity() {
image_timer.setImageResource(R.drawable.icon_timer_off)
}
}
private lateinit var sensorOrientationListener: SensorOrientationListener
private var previousOrientation: Float = 0f
private lateinit var orientedIcons: List<ImageView>
private lateinit var gocryptfsVolume: GocryptfsVolume
private lateinit var outputDirectory: String
private lateinit var fileName: String
@ -72,6 +79,8 @@ class CameraActivity : BaseActivity() {
}
})
take_photo_button.onClick = ::onClickTakePhoto
orientedIcons = listOf(image_hdr, image_timer, image_grid, image_close, image_flash, image_camera_switch)
sensorOrientationListener = SensorOrientationListener(this)
}
private fun onClickTakePhoto() {
@ -192,13 +201,37 @@ class CameraActivity : BaseActivity() {
override fun onPause() {
super.onPause()
sensorOrientationListener.remove(this)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){ //if not asking for permission
finish()
}
}
override fun onResume() {
super.onResume()
sensorOrientationListener.addListener(this)
}
override fun onBackPressed() {
super.onBackPressed()
isFinishingIntentionally = true
}
override fun onOrientationChange(newOrientation: Int) {
val reversedOrientation = when (newOrientation){
90 -> 270
270 -> 90
else -> newOrientation
}.toFloat()
val rotateAnimation = RotateAnimation(previousOrientation, when {
reversedOrientation - previousOrientation > 180 -> reversedOrientation - 360
reversedOrientation - previousOrientation < -180 -> reversedOrientation + 360
else -> reversedOrientation
}, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f)
rotateAnimation.duration = 300
rotateAnimation.interpolator = LinearInterpolator()
rotateAnimation.fillAfter = true
orientedIcons.map { it.startAnimation(rotateAnimation) }
previousOrientation = reversedOrientation
}
}

View File

@ -0,0 +1,95 @@
package sushi.hardcore.droidfs
import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import java.lang.ref.WeakReference
import java.util.*
class SensorOrientationListener(context: Context) {
private val mSensorEventListener: SensorEventListener
private val mSensorManager: SensorManager
init {
mSensorEventListener = NotifierSensorEventListener()
mSensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
}
private val mListeners = ArrayList<WeakReference<Listener?>>(3)
private var orientation = 0
private fun onResume() {
mSensorManager.registerListener(
mSensorEventListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL
)
}
private fun onPause() {
mSensorManager.unregisterListener(mSensorEventListener)
}
private inner class NotifierSensorEventListener : SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
val x = event.values[0]
val y = event.values[1]
var newOrientation: Int = orientation
if (x < 5 && x > -5 && y > 5) newOrientation = 0
else if (x < -5 && y < 5 && y > -5) newOrientation = 90
else if (x < 5 && x > -5 && y < -5) newOrientation = 180
else if (x > 5 && y < 5 && y > -5) newOrientation = 270
if (orientation != newOrientation) {
orientation = newOrientation
notifyListeners()
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}
interface Listener {
fun onOrientationChange(newOrientation: Int)
}
fun addListener(listener: Listener) {
if (get(listener) == null) // prevent duplications
mListeners.add(WeakReference(listener))
if (mListeners.size == 1) {
onResume() // this is the first client
}
}
fun remove(listener: Listener) {
val listenerWR = get(listener)
remove(listenerWR)
}
private fun remove(listenerWR: WeakReference<Listener?>?) {
if (listenerWR != null) mListeners.remove(listenerWR)
if (mListeners.size == 0) {
onPause()
}
}
private operator fun get(listener: Listener): WeakReference<Listener?>? {
for (existingListener in mListeners) if (existingListener.get() === listener) return existingListener
return null
}
private fun notifyListeners() {
val deadListeners = ArrayList<WeakReference<Listener?>>()
for (wr in mListeners) {
if (wr.get() == null)
deadListeners.add(wr)
else
wr.get()!!.onOrientationChange(orientation)
}
// remove dead references
for (wr in deadListeners) {
mListeners.remove(wr)
}
}
}