I have a simple activity running my OpenCV application. The app should detect objects from camera and visualize them on a custom SurfaceView. I want to lock the device orientation in portrait mode and rotate my widgets programmatically as the standard camera app does.
Here is the activity layout. It includes OpenCV CameraView and a fragment widget shown above it.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.chessking.android.vision.ui.widget.ExtendedCameraView
android:id="@+id/track_camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
opencv:camera_id="any"
opencv:show_fps="true"/>
<FrameLayout
android:id="@+id/track_fragment_container"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true">
<fragment
android:id="@+id/track_board_preview"
class="com.chessking.android.vision.ui.BoardWidgetFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
<Button
android:id="@+id/track_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="16dp"
android:text="@string/scan_action"/>
</RelativeLayout>
Custom SurfaceView
is presented in the fragment layout. It is com.convekta.android.chessboard.ChessPanel
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/board_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/boardBackground"
android:orientation="vertical">
<include layout="@layout/widget_board_clock_both" />
<com.convekta.android.chessboard.ChessPanel
android:id="@+id/board_panel"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/board_background_transparent"
app:chessPanelBackground="@color/board_background_transparent"
app:chessPanelBorderColor="@color/board_border"
app:chessPanelBorderWidth="1dp"/>
<com.convekta.android.chessboard.NotationView
android:id="@+id/nota"
android:layout_width="match_parent"
android:layout_height="20dp"
android:clipChildren="false"
android:fadeScrollbars="false" />
</LinearLayout>
When I need to rotate the widget layour, I change rotation
property of the board_layout
.
boardLayout.rotation = degrees.toFloat()
The problem is the rotation works on Android 9, but the canvas is misplaced on Android. Here are screenshots from Android 6 emulator, in portrait mode the app looks normal, in landscape SurfaceView jumps out of its layout.