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