【问题标题】:CameraX: Animated ZoomCameraX:动画缩放
【发布时间】:2021-08-28 02:15:55
【问题描述】:

我正在开发一个相机应用程序,我想要双击来缩放。我能够实现这一点,但后来我想通过动画缩放来改进应用程序的用户体验。我尝试应用 Ticker 逻辑来做到这一点,但从 CameraX API 执行简单的缩放调用需要自己的时间(高到无法在流畅的动画中使用它。有什么方法可以从当前动画缩放将值缩放到期望值?

代码:

            public boolean onDoubleTap(MotionEvent e) {
                Log.i(TAG, "===============Double tap detected.=========");

                final ZoomState zoomState = camera.getCameraInfo().getZoomState().getValue();
                float start, diff;

                if(zoomState!=null) {
                    start = zoomState.getZoomRatio();
                    diff = start * 0.5f;

                    final Calendar calendar = Calendar.getInstance();
                    final int ANIM_DURATION_IN_MS = 2000;
                    final long endTime = Calendar.getInstance().getTimeInMillis() + ANIM_DURATION_IN_MS;

                    double elapsed = 1.0;

                    while(elapsed>0.0) {
                        elapsed = endTime - Calendar.getInstance().getTimeInMillis();
                        double d = 1 - elapsed/(float)ANIM_DURATION_IN_MS;

                        Log.i(TAG, "getTime: " + Calendar.getInstance().getTimeInMillis());
                        Log.i(TAG, "endTime: " + endTime);
                        Log.i(TAG, "d: " + d);

                        try {
                            camera.getCameraControl().setZoomRatio((float) (start+(diff*d))).get();
                        } catch (ExecutionException | InterruptedException executionException) {
                            executionException.printStackTrace();
                        }
                        Log.i(TAG, "zoomRatio: " + (float) (start+diff*d));
                    }

                    Log.i(TAG, "Done");

                    camera.getCameraControl().setZoomRatio(start+diff);
                }

                return super.onDoubleTap(e);
            }

【问题讨论】:

    标签: java android android-camerax


    【解决方案1】:

    您可以在短时间内逐步将缩放级别更改为所需的缩放级别以创建此动画,但您可以使用 CameraX 中的线性缩放来代替缩放比例,这将为您提供平滑的过渡,并且易于实现:

    linearZoomSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {        
        override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
            cameraControl.setLinearZoom(progress / 100f)
        }
    
        override fun onStartTrackingTouch(seekBar: SeekBar?) {}
    
        override fun onStopTrackingTouch(seekBar: SeekBar?) {}
    })
    

    此示例使用搜索栏,但您可以使用自动更改其值的值动画器来执行此操作。

    线性缩放值动画设置示例:

    // Initializing the animator with values to zoom - min:0f - max:1f
    ValueAnimator animator = ValueAnimator.ofFloat(0.1f, 0.2f, 0.3f, 0.4f, 0.5f);
    // Setting animation duration
    animator.setDuration(200);
    // Adding listener for every value update of the animation
    animator.addUpdateListener(valueAnimator -> camera.getCameraControl().setLinearZoom((float) valueAnimator.getAnimatedValue()));
    // Start the zoom animation
    animator.start();
    

    在值动画器的初始化中放入的值越多,动画看起来就越平滑。

    【讨论】:

    • 您好,非常感谢您的帮助。我将很快在我的代码中测试这个答案。你能帮我看看这个吗? stackoverflow.com/questions/68957701/…
    • 感谢您推荐 ValueAnimator,它使代码更具可读性:) 该解决方案按预期工作。
    猜你喜欢
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多