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.text.InputType
import android.view.View import android.view.View
import android.view.WindowManager 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.EditText
import android.widget.ImageView
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.otaliastudios.cameraview.CameraListener import com.otaliastudios.cameraview.CameraListener
@ -25,7 +29,7 @@ import java.io.ByteArrayInputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
class CameraActivity : BaseActivity() { class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
companion object { companion object {
private val flashModes = listOf(Flash.AUTO, Flash.ON, Flash.OFF) 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) 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) 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 gocryptfsVolume: GocryptfsVolume
private lateinit var outputDirectory: String private lateinit var outputDirectory: String
private lateinit var fileName: String private lateinit var fileName: String
@ -72,6 +79,8 @@ class CameraActivity : BaseActivity() {
} }
}) })
take_photo_button.onClick = ::onClickTakePhoto 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() { private fun onClickTakePhoto() {
@ -192,13 +201,37 @@ class CameraActivity : BaseActivity() {
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
sensorOrientationListener.remove(this)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){ //if not asking for permission if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){ //if not asking for permission
finish() finish()
} }
} }
override fun onResume() {
super.onResume()
sensorOrientationListener.addListener(this)
}
override fun onBackPressed() { override fun onBackPressed() {
super.onBackPressed() super.onBackPressed()
isFinishingIntentionally = true 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)
}
}
}