fix: Move PreviewView into SurfaceView to make it simpler (#2566)

* hmmm

* Set initial fixed size

* fix: Repair PreviewView again

* Update PreviewView.kt
This commit is contained in:
Marc Rousavy 2024-02-15 17:07:57 +01:00 committed by GitHub
parent c5646ca1e2
commit bcd12649e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -5,12 +5,9 @@ import android.content.Context
import android.graphics.Point
import android.util.Log
import android.util.Size
import android.view.Gravity
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.widget.FrameLayout
import com.facebook.react.bridge.UiThreadUtil
import com.mrousavy.camera.extensions.installHierarchyFitter
import com.mrousavy.camera.extensions.resize
import com.mrousavy.camera.extensions.rotatedBy
import com.mrousavy.camera.types.Orientation
@ -21,26 +18,30 @@ import kotlinx.coroutines.withContext
@SuppressLint("ViewConstructor")
class PreviewView(context: Context, callback: SurfaceHolder.Callback) :
FrameLayout(context),
SurfaceView(context),
SurfaceHolder.Callback {
var size: Size = CameraDeviceDetails.getMaximumPreviewSize()
private set
set(value) {
if (field != value) {
Log.i(TAG, "Surface Size changed: $field -> $value")
field = value
updateLayout()
}
}
var resizeMode: ResizeMode = ResizeMode.COVER
set(value) {
field = value
UiThreadUtil.runOnUiThread {
Log.i(TAG, "Setting PreviewView ResizeMode to $value...")
requestLayout()
invalidate()
if (field != value) {
Log.i(TAG, "Resize Mode changed: $field -> $value")
field = value
updateLayout()
}
}
private var inputOrientation: Orientation = Orientation.LANDSCAPE_LEFT
set(value) {
field = value
UiThreadUtil.runOnUiThread {
Log.i(TAG, "Camera Input Orientation changed to $value!")
requestLayout()
invalidate()
if (field != value) {
Log.i(TAG, "Input Orientation changed: $field -> $value")
field = value
updateLayout()
}
}
private val viewSize: Size
@ -50,35 +51,25 @@ class PreviewView(context: Context, callback: SurfaceHolder.Callback) :
val dpY = height / displayMetrics.density
return Size(dpX.toInt(), dpY.toInt())
}
private val surfaceView = SurfaceView(context)
init {
Log.i(TAG, "Creating PreviewView...")
this.installHierarchyFitter()
surfaceView.layoutParams = LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT,
Gravity.CENTER
)
surfaceView.holder.setKeepScreenOn(true)
surfaceView.holder.addCallback(this)
surfaceView.holder.addCallback(callback)
addView(surfaceView)
holder.setKeepScreenOn(true)
holder.addCallback(this)
holder.addCallback(callback)
holder.setFixedSize(size.width, size.height)
}
override fun surfaceCreated(holder: SurfaceHolder) = Unit
override fun surfaceDestroyed(holder: SurfaceHolder) = Unit
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
Log.i(TAG, "PreviewView Surface size changed: $size -> ${width}x$height, re-computing layout...")
size = Size(width, height)
requestLayout()
invalidate()
}
suspend fun setSurfaceSize(width: Int, height: Int, cameraSensorOrientation: Orientation) {
withContext(Dispatchers.Main) {
inputOrientation = cameraSensorOrientation
surfaceView.holder.resize(width, height)
holder.resize(width, height)
}
}
@ -92,8 +83,14 @@ class PreviewView(context: Context, callback: SurfaceHolder.Callback) :
return rotated
}
private fun updateLayout() {
UiThreadUtil.runOnUiThread {
requestLayout()
invalidate()
}
}
private fun getSize(contentSize: Size, containerSize: Size, resizeMode: ResizeMode): Size {
// TODO: Take sensor orientation into account here
val contentAspectRatio = contentSize.width.toDouble() / contentSize.height
val containerAspectRatio = containerSize.width.toDouble() / containerSize.height