From bcd12649e2c8297c39bba07626a9b4ae12bda7d4 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Thu, 15 Feb 2024 17:07:57 +0100 Subject: [PATCH] fix: Move PreviewView into SurfaceView to make it simpler (#2566) * hmmm * Set initial fixed size * fix: Repair PreviewView again * Update PreviewView.kt --- .../com/mrousavy/camera/core/PreviewView.kt | 59 +++++++++---------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/package/android/src/main/java/com/mrousavy/camera/core/PreviewView.kt b/package/android/src/main/java/com/mrousavy/camera/core/PreviewView.kt index 02ad602..ba3c94b 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/PreviewView.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/PreviewView.kt @@ -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