3

Context:

In the android-7.1.1_r12 api, the android.hardware.camera2 uses a StickyBottomCaptureLayout as a "BottomBar" to display the action buttons (as switch-camera, shutter and recent picture buttons). Whatever the device orientation, this StickyBottomCaptureLayout is displayed always above/near the system bar (which has back, home and other apps buttons).

For example, this is what it looks when the rotation degree is 0 or 180:

Camera api with stickybottomcapturelayout and bottombar at bottom

And, by orienting the device and get a rotation degree as 90 or 270, the StickyBottomCaptureLayout is now near the system bar:

Camera api with stickybottomcapturelayout and bottombar at right

Usually, this above screenshot should has the sticky bar on the left and camera on the right...

Tries:

  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
    }
    

However, this is not working at all. I don't know how these widgets make it work properly.

Question:

Does someone has a solution to reproduce the case of the bottom bar when the device orientation is changing (always above or near the Android system bar)? Keeping in mind that my minimum SDK is below 21, so I have no access to android.hardware.camera2 api.

4

1 回答 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应用程序一样的平滑方向这个答案。使用方向监听器和configChanges选项,我可以在没有默认旋转动画的情况下重新组织视图。我设置了正确的位置onLayout()并调用invalidate(). ;)

于 2017-03-05T19:17:11.267 回答