【问题标题】:my CameraX with viewmodel not surviving configuration changes我的带有 viewmodel 的 CameraX 无法在配置更改中幸存
【发布时间】:2021-02-11 17:29:00
【问题描述】:

我是 android 新手,第一次实现 viewmodel。我的视图模型的目标是在设备方向变化中幸存下来。我使用 CameraX 作为它的相机应用程序。不幸的是,它无法在方向更改中幸存下来。这是我提供 ProcessCameraProvider 的视图模型。

ViewModelCamera.kt

class ViewModelCamera(application:Application) : AndroidViewModel(application){
    private val getProcessCameraProvider by lazy {
        MutableLiveData<ProcessCameraProvider>().apply {
            val cameraProviderFuture=ProcessCameraProvider.getInstance(getApplication())
            cameraProviderFuture.addListener(
                {
                    try{
                        value=cameraProviderFuture.get()

                    }catch (exc :ExecutionException){
                        throw IllegalStateException("failed to retrieve camera process",exc)
                    }catch (exc:InterruptedException){
                        throw IllegalStateException("failed to retrieve camera process",exc)
                    }
                },ContextCompat.getMainExecutor(getApplication())
            )
        }
    }
    val processCameraProvider:LiveData<ProcessCameraProvider>
        get() = getProcessCameraProvider
}

这是在MainActivity.kt

中初始化和使用的
  private lateinit var cameraProvider: ProcessCameraProvider

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setupViewModel()
        bindingMainActivity = ActivityMainBinding.inflate(layoutInflater)
        setContentView(bindingMainActivity.root)
        
        sharedPrefs=sharedPref(applicationContext)
        if (isPermissionGranted()){
           try {
                tryStartCamera()
                bindingMainActivity.viewFinder.scaleType = if(!sharedPrefs.getPref("AspectRatio")) PreviewView.ScaleType.FILL_CENTER else PreviewView.ScaleType.FIT_CENTER
             }catch (e: Exception) {
                Toast.makeText(this, R.string.NotSupportMessage, Toast.LENGTH_SHORT).show()
                finishAffinity()
            }
        } else {
            requestPermission()
        }

     private fun setupViewModel(){
        val vm=ViewModelProvider(this).get(ViewModelCamera::class.java)
        vm.processCameraProvider.observe(
            this, {
                cameraProvider = it ?: return@observe
                tryStartCamera()
            }
        )
    }

    private fun tryStartCamera() {
        if(::cameraProvider.isInitialized && isPermissionGranted()){
            startCamera(cameraProvider)
        }
    }

    private fun startCamera(cameraProvider: ProcessCameraProvider) {
            // Preview
            preview = Preview.Builder()
                .build()
            imageCapture = ImageCapture.Builder()
                .setFlashMode(flashMode)
                .setTargetAspectRatio(ASPECTRATIO)
                .setCaptureMode(LATENCY)
                .build()
     
            val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
            try {
                // Unbind use cases before rebinding
                cameraProvider.unbindAll()
                // Bind use cases to camera
                camera = cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview, imageCapture
                )
                preview?.setSurfaceProvider(bindingMainActivity.viewFinder.surfaceProvider)
            } catch (exc: Exception) {
                Log.e("CameraX", "Use case binding failed", exc)
            }
    }

我有 2 个用于纵向和横向的布局 xml。 2布局是否会导致强制重启?

我知道我做错了,但我不知道是什么。我是否需要保存任何其他对象或整个实现是错误的。谢谢。

编辑

肖像的横向版本 - 是我不重启的期望

我在清单中覆盖配置时得到的视图

纵向的原始主视图

如何在不重新启动的情况下获取链接第一张图片。

【问题讨论】:

    标签: android kotlin android-livedata android-viewmodel


    【解决方案1】:

    Does 2 layout cause force restart ? 是的!如果您的手机旋转时有两种布局(一种用于纵向,一种用于横向),则将再次调用 onCreate 方法。如果您想保留实际状态,请使用 onSaveInstanceState 保存实际 UI 状态并在 onCreate(savedInstanceState: Bundle?) 中检索它

    编辑

    如果您希望旋转时出现该状态,则将 Activity 的方向定义为纵向,以便在旋转手机时不会改变。

    <activity
        android:name=".MainActivity"
        android:screenOrientation="portrait" />
    

    【讨论】:

    • 感谢您的信息。但是如何将 ImageButtons 放入捆绑包中?我没有像 string 这样的数据可以存储在 bundle 上。我不知道该怎么做你能告诉我一些例子或任何其他来源
    • 我不明白你所说的“ImageButton”是什么意思。您可以拍摄照片(纵向状态),将 URL 结果保存在捆绑包中,如果用户旋转手机,则检索最后一个 URL 并将其显示在您的横向图像视图中。
    • 如果您期望第一张照片状态,则不需要横向布局
    • 这怎么可能,如果我没有横向布局,它会像我尝试过的第二张图片。
    猜你喜欢
    • 2023-04-04
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多