Android has released a new API camerax in recent months. I'm trying to understand how to get auto-focusing for the camera to work.

https://groups.google.com/a/android.com/forum/#!searchin/camerax-developers/auto$20focus|sort:date/camerax-developers/IQ3KZd8iOIY/LIbrRIqEBgAJ

这里有一个关于这个主题的讨论,但几乎没有关于它的具体文档.

https://github.com/android/camera-samples/tree/master/CameraXBasic/app/src/main/java/com/android/example/cameraxbasic

这也是基本的camerax应用程序,但我找不到任何关于自动对焦的文件.

Any tips or points to documentation is helpful. Also I'm fairly new to android so its very possible I'm missing something that makes the above links more useful.

推荐答案

使用当前的CameraX 1.0.0,您可以通过以下两种方式进行操作:

  1. 每X秒自动对焦一次:

  2. Focus on-tap:

     previewView.afterMeasured {
         previewView.setOnTouchListener { _, event ->
             return@setOnTouchListener when (event.action) {
                 MotionEvent.ACTION_DOWN -> {
                     true
                 }
                 MotionEvent.ACTION_UP -> {
                     val factory: MeteringPointFactory = SurfaceOrientedMeteringPointFactory(
                         previewView.width.toFloat(), previewView.height.toFloat()
                     )
                     val autoFocusPoint = factory.createPoint(event.x, event.y)
                     try {
                         camera.cameraControl.startFocusAndMetering(
                             FocusMeteringAction.Builder(
                                 autoFocusPoint,
                                 FocusMeteringAction.FLAG_AF
                             ).apply {
                                 //focus only when the user tap the preview
                                 disableAutoCancel()
                             }.build()
                         )
                     } catch (e: CameraInfoUnavailableException) {
                         Log.d("ERROR", "cannot access camera", e)
                     }
                     true
                 }
                 else -> false // Unhandled event.
             }
         }
     }
    

afterMeasured扩展函数是一个简单的实用程序:(感谢ch271828n提供improving it)

inline fun View.afterMeasured(crossinline block: () -> Unit) {
    if (measuredWidth > 0 && measuredHeight > 0) {
        block()
    } else {
        viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.GlobalLayoutListener {
            override fun onGlobalLayout() {
                if (measuredWidth > 0 && measuredHeight > 0) {
                    viewTreeObserver.removeOnGlobalLayoutListener(this)
                    block()
                } 
            }
        })
    }
}

使用以下命令可以获得Camera个对象

val camera = cameraProvider.bindToLifecycle(
    this@Activity, cameraSelector, previewView //this is a PreviewView
)

Kotlin相关问答推荐

这些Kotlin函数等效吗?

如何在Kotlin中为接受varargs的函数添加带有默认值的新参数?

某些公共函数显然不能在类实例上访问;Klaxon示例

编译后的JavaFX应用程序立即以静默方式崩溃

Kotlin:类型不匹配:推断的类型已运行,但应等待

数据源配置

如何通过更改现有数据类型来执行Android房间数据库迁移?

如何使用 Firebase 和 Kotlin 在文本 (Jetpack Compose) 中显示当前用户名?

Jetpack Compose 中的连续重组

使用 Compose for Desktop Bundle 文件

使用 Discord4j 交叉发布 Discord 消息

Jetpack compose 可滚动表格

kotlin,如何从函数返回类类型

将 @Component.Builder 与构造函数参数一起使用

Kotlin:找不到符号类片段或其他 android 类

Kotlin-通过与属性列表进行比较来筛选对象列表

Kotlin/JS,Gradle 插件:无法加载@webpack-cli/serve命令

创建Spring和#180的实例;Kotlin中的参数化类型引用

在Kotlin中创建通用二维数组

在 IntelliJ Idea 中未为 Kotlin @ConfigurationProperties 类生成 spring-configuration-metadata.json 文件