android - 如何在 camera2 Android api 中创建一个 BottomBar 作为 StickyBottomCaptureLayout?

标签 android android-layout android-orientation android-camera2 android-bottomnav

上下文:

android-7.1.1_r12 api 中,android.hardware.camera2 使用 StickyBottomCaptureLayout作为"BottomBar"显示操作按钮(如切换相机、快门和最近的图片按钮)。无论设备方向如何,此 StickyBottomCaptureLayout 始终显示在系统栏上方/附近(具有返回、主页和其他应用程序按钮)。

例如,这是旋转度数为 0180 时的样子:

Camera api with stickybottomcapturelayout and bottombar at bottom

并且,通过定位设备并获得 90270 的旋转度数,StickyBottomCaptureLayout 现在靠近系统栏:

Camera api with stickybottomcapturelayout and bottombar at right

通常,上面的截图应该有左边的粘性条和右边的相机......

尝试:

  1. 我首先尝试使用 layout-land 设置不同的布局,但没有成功!我无法更改默认的从左到右的方向,也无法让底部栏以 270 度固定在 Android 系统栏上。

  2. 我无法扩展 these widgets ,但我试图重现这个案例。例如,我有两种布局:

    <FrameLayout>
        <ViewGroup .../> // containing the upper views
    
        <StickyBottomBar .../> // same behavior as StickyBottomCaptureLayout
    </FrameLayout>
    

    在每次方向变化时,我都会获取旋转设备并为上层布局和粘性条设置正确的重力,如下所示:

    if (rotation == 0) {
        // views gravity = TOP
        // sticky gravity = BOTTOM
    } else if (rotation == 90) {
        // views gravity = LEFT
        // sticky gravity = RIGHT
    } else if (rotation == 180) { 
        // views gravity = BOTTOM
        // sticky gravity = TOP
    } else if (rotation == 270) { 
        // views gravity = RIGHT
        // sticky gravity = LEFT
    }
    

但是,这根本不起作用。我不知道这些小部件如何使其正常工作。

问题:

当设备方向发生变化时(总是在 Android 系统栏上方或附近),是否有人有重现底部栏情况的解决方案?请记住,我的最低 SDK 低于 21,因此我无法访问 android.hardware.camera2 api。

最佳答案

我刚刚找到了解决方案:我需要为每个布局设置一个 RectF 并使用正确的坐标设置它们From the source class ,我设法做到这一点:

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    // rotation from context Surface.ROTATION
    int degrees = getDeviceRotation(getContext());
    // size of the sticky bottom bar
    int offsetSize = (int) getResources().getDimension(R.dimen.sticky_bar_default_size);

    // layout sticky bottom bar
    RectF bottomBarRect = getStickyBarRect(degrees, offsetSize);
    mBottomBar.layout((int) bottomBarRect.left, (int) bottomBarRect.top,
            (int) bottomBarRect.right, (int) bottomBarRect.bottom);

    // layout upper view
    RectF upperViewRect = getUpperViewRect(degrees, offsetSize);
    mUpperView.layout(...); // same logic as above

    invalidate();
}

// Gets the coordinates positions to set the Sticky Bottom Bar
private RectF getStickyBarRect(int degrees, int offsetSize) {
    float left = 0, top = 0, right = 0, bottom = 0;
    int width = getWidth();
    int height = getHeight();

    if (degrees == 0) { // stickybar at bottom
        top = height - offsetSize;
        right = width;
        bottom = height;
    } else if (degrees == 90) { // stickybar at right
        left = width - offsetSize;
        right = width;
        bottom = height;
    } else if (degrees == 180) { // stickybar at top
        right = width;
        bottom = height - offsetSize;
    } else if (degrees == 270) { // stickybar at left
        right = offsetSize;
        bottom = height;
    }

    return new RectF(left, top, right, bottom);
}

// Gets the coordinates positions to set the upper views
private RectF getUpperViewRect(int degrees, int offsetSize) {
    // same logic as getStickyBarRect()
}

这按预期工作!


我找到了一种方法来重现像 native camera2 应用程序一样的平滑方向 this answer .使用方向监听器和 configChanges 选项,我能够在没有默认旋转动画的情况下重新组织 View 。我在 onLayout() 中设置了正确的位置并调用了 invalidate()。 ;)

关于android - 如何在 camera2 Android api 中创建一个 BottomBar 作为 StickyBottomCaptureLayout?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42612692/

相关文章:

android - 约束布局 : How to constrain a View's top to the bottom of the view of largest height?

Android:暂时禁用 Activity 中的方向更改

java - 资源文件(color.xml、string.xml、style.xml)

android - -webkit-filter 无法在 Android cordova 应用程序中正常工作

android - 在 ListView 中访问特定项目的布局

android - 我可以根据特定逻辑禁用特定 BottomNavigationView 项目的移动吗?

android - 如何在方向更改时使用 onSaveInstanceState 和 onRestoreInstanceState 保存状态

android - 如何在 Android 中禁用横向模式?

android - 如何在 FragmentStatePagerAdapter 中动态添加页面

android - 回合制游戏,哪种抽奖方式好?