Как создать BottomBar в виде StickyBottomCaptureLayout в Camera2 Android API?
Контекст:
в android-7.1.1_r12
API, android.hardware.camera2
использует StickyBottomCaptureLayout
как "BottomBar"
для отображения кнопок действий (таких как кнопки переключения камеры, затвора и недавних изображений). Независимо от ориентации устройства, это StickyBottomCaptureLayout
всегда отображается над / рядом с системной панелью (на которой есть кнопки "Назад", "Домой" и "Другие").
Например, это то, что выглядит, когда степень вращения 0
или же 180
:
И, ориентируя устройство и получить степень вращения как 90
или же 270
, StickyBottomCaptureLayout
сейчас возле системной панели:
Как правило, этот скриншот должен иметь полоску слева и камеру справа...
Пытается:
Сначала я попытался установить другой макет с
layout-land
, но не повезло! Я не могу изменить стандартную ориентацию слева направо и привязать нижнюю панель к системной панели Android на270
градусов.Я не могу расширить эти виджеты, но я попытался воспроизвести случай. Например, я получил два макета:
<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
апи.
1 ответ
Я только что нашел решение: мне нужно установить 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()
,;)