如何在camera2 Android api中创建BottomBar作为StickyBottomCaptureLayout?

时间:2017-03-05 19:05:25

标签: 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
    }
    
  3. 然而,这根本不起作用。我不知道这些小部件如何使其正常工作。

    问题:

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

1 个答案:

答案 0 :(得分:3)

我刚刚找到解决方案:我需要为每个布局设置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()
}

这可以按预期工作!

我找到了一种方法来重现平滑方向,就像使用this answer的原生camera2应用一样。使用方向监听器和configChanges选项,我可以在没有默认旋转动画的情况下重新组织视图。我在onLayout()中设置了正确的职位,并致电invalidate()。 ;)