Search code examples
androidscrollbarwear-os

Curved scrollbars and BoxInsetLayout


I created a confirmation activity to get the approval of the user to proceed with an action. I created the activity using the non-deprecated android.support.wear.widget.BoxInsetLayout.

Unfortunately the description becomes longer than the screen can display and the buttons get cut-off and it is not possible to scroll down. I tried adding a ScrollView and some scrollbar attributes but i could not get it working.

Looking at some confirmation activities within the android wear system, it is indeed possible to get a BoxInsetLayout with curved scrollbars.

How can I enable the BoxInsetLayout to be scrollable in curved mode? Do I have to stack a WearableRecyclerView and a BoxInsetLayout?

Looking forward for your answers. Thanks in advance!

Image:

Examples for broken and scrollable BoxInsetLayout

Activities layout xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.wear.widget.BoxInsetLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/dark_grey">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    app:boxedEdges="all">

    <TextView
        android:id="@+id/text_description"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        android:fontFamily="sans-serif-condensed"
        android:gravity="bottom|center"
        android:text=""
        android:textSize="14sp" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        android:layout_marginTop="4dp"
        android:fontFamily="sans-serif-condensed"
        android:gravity="bottom|center"
        android:text="@string/warning_question_colorful_ambient"
        android:textSize="16sp" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        android:layout_marginTop="4dp">

        <android.support.wearable.view.CircledImageView
            android:id="@+id/button_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="start|end"
            android:src="@drawable/ic_close_24dp"
            app:circle_color="#AFAFAF"
            app:circle_radius="25dp"
            app:circle_radius_pressed="20dp" />

        <android.support.wearable.view.CircledImageView
            android:id="@+id/button_ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end|bottom"
            android:src="@drawable/ic_check_24dp"
            app:circle_color="#0EB695"
            app:circle_radius="25dp"
            app:circle_radius_pressed="20dp" />
    </FrameLayout>
</LinearLayout>

</android.support.wear.widget.BoxInsetLayout>

Solution

  • I found a appropriate solution for my problem: I scrapped the BoxInsetLayout. It seems just not possible to get this layout scrollable.

    As an alterative I simply use a ScrollView with an LinearLayout as child. The ScrollView supports curved scrollbars by itself and to support round screens I calculate the inset myself and apply it as padding to the LinearLayout.

    The Solution

    I wrote a blog post about this specific problem and the solution: https://www.journal.deviantdev.com/android-wear-scrollable-boxinsetlayout/

    Furthermore I made a snippet with the solution and uploaded it to Bitbucket: https://bitbucket.org/snippets/devdev-dev/keR67A

    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:id="@+id/layout_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            [..]
        </LinearLayout>
    

    override fun onCreate(savedInstanceState: Bundle?) {
        [..]
        adjustInset()
    }
    
    private fun adjustInset() {
        if (applicationContext.resources.configuration.isScreenRound) {
            val inset = (FACTOR * displayMetrics.widthPixels).toInt()
            layout_content.setPadding(inset, inset, inset, inset)
        }
    }
    
    companion object {
        private const val FACTOR = 0.146467f // c = a * sqrt(2)
    }