如何在camera2 Android api中创建一个StickyBottomCaptureLayout作为底部栏?

4

背景:

android-7.1.1_r12 api中,android.hardware.camera2使用StickyBottomCaptureLayout作为“BottomBar”显示操作按钮(例如切换摄像头、快门和最近照片等按钮)。无论设备方向如何,这个StickyBottomCaptureLayout始终显示在系统栏的上方/附近(其中包含返回、主页和其他应用程序按钮)。

例如,当旋转角度为0180时,其外观如下:

Camera api with stickybottomcapturelayout and bottombar at bottom

通过将设备旋转并获得旋转角度为90270StickyBottomCaptureLayout现在接近系统栏:

Camera api with stickybottomcapturelayout and bottombar at right

通常,这个截图应该让粘性工具栏在左侧,相机在右侧...

尝试:

  1. I firstly tried to set different layout with layout-land, but no luck! I cannot change the default left-to-right orientation and get the bottom bar sticks to the Android system bar on 270 degrees.

  2. I cannot extend these widgets, but I tried to reproduce the case. For example, I got two layouts:

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

    On each orientation changes, I get the rotation's device and set the correct gravity for upper layout and the sticky bar, something as follows:

    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。
1个回答

3
我刚刚找到了解决方案:我需要为每个布局设置一个RectF,并将它们设置为正确的坐标从源类中,我成功做到了这一点:
@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()
}

这个按预期工作!


我发现了一种方法可以重现类似于原生camera2应用程序的平滑方向,this answer中提供了详细的说明。使用方向监听器和configChanges选项,我能够重新组织视图而不使用默认的旋转动画。我在onLayout()中设置正确的位置并调用invalidate()。;)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接