Correctly styling Android Home Widget size
Asked Answered
K

1

7

I try to display up to three elements in my Home Widget according to how many rows a user expanded the widget to. (1-3 should be allowed)

So the height of each element should be the height of one row. The main goal would be that it looks correct on every device.

This is my layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/shape_roundedcorners_white">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/article1"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal"
        android:layout_margin="@dimen/widget_margin"
        android:background="#0000ff">

        <ImageView
            android:id="@+id/article1img"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:gravity="center"
            android:layout_gravity="center"
            android:layout_marginRight="15dp"
            android:layout_marginLeft="10dp"
            android:src="@drawable/ic_notifications" />

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_margin="@dimen/inner_widget_margin">

            <TextView
                android:id="@+id/article1Title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:contentDescription="@string/appwidget_text"
                android:gravity="left"
                android:text="@string/appwidget_title"
                android:textColor="#000000"
                android:textSize="14sp"
                android:textStyle="bold"/>
            <TextView
                android:id="@+id/article1Text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:contentDescription="@string/appwidget_text"
                android:gravity="left"
                android:text="@string/appwidget_text"
                android:textColor="#000000"
                android:textSize="12sp"/>
        </LinearLayout>

    </LinearLayout>


    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:orientation="vertical"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        style="@style/Divider">
        <!--<View style="@style/Divider"/>-->
    </LinearLayout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/article2"
        android:layout_width="match_parent"
        android:layout_height="85dp"
        android:orientation="horizontal"
        android:layout_margin="@dimen/widget_margin"
        android:background="#ffffff">

        <ImageView
            android:id="@+id/article2img"
            android:layout_width="40dp"
            android:layout_height="35dp"
            android:gravity="center"
            android:layout_gravity="center"
            android:layout_marginRight="15dp"
            android:layout_marginLeft="10dp"
            android:src="@drawable/ic_notifications" />

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="35pt"
            android:orientation="vertical"
            android:layout_margin="@dimen/inner_widget_margin"
            android:background="#ffffff">
            <TextView
                android:id="@+id/article2Title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:contentDescription="@string/appwidget_text"
                android:gravity="left"
                android:text="@string/appwidget_title"
                android:textColor="#000000"
                android:textSize="14sp"
                android:textStyle="bold"/>
            <TextView
                android:id="@+id/article2Text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:contentDescription="@string/appwidget_text"
                android:gravity="left"
                android:text="@string/appwidget_text"
                android:textColor="#000000"
                android:textSize="12sp"/>
        </LinearLayout>
    </LinearLayout>


    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:orientation="vertical"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        style="@style/Divider">
        <!--<View style="@style/Divider"/>-->
    </LinearLayout>


    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/article3"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal"
        android:layout_margin="@dimen/widget_margin"
        android:background="#ffffff">

        <ImageView
            android:id="@+id/article3img"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:gravity="center"
            android:layout_gravity="center"
            android:layout_marginRight="15dp"
            android:layout_marginLeft="10dp"
            android:src="@drawable/ic_notifications" />

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="35pt"
            android:orientation="vertical"
            android:layout_margin="@dimen/inner_widget_margin"
            android:background="#ffffff">
            <TextView
                android:id="@+id/article3Title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:contentDescription="@string/appwidget_text"
                android:gravity="left"
                android:text="@string/appwidget_title"
                android:textColor="#000000"
                android:textSize="14sp"
                android:textStyle="bold"/>
            <TextView
                android:id="@+id/article3Text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:contentDescription="@string/appwidget_text"
                android:gravity="left"
                android:text="@string/appwidget_text"
                android:textColor="#000000"
                android:textSize="12sp"/>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

with

<dimen name="widget_margin">8dp</dimen>
<dimen name="inner_widget_margin">2dp</dimen>

and

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid
        android:color="#ffffff"/>
    <corners
        android:radius="12dp"/>
</shape>

I read here that the height of one row should be about 40dp which is why I set my article1 - Layout to 40dp and my info to

<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialKeyguardLayout="@layout/news_widget"
    android:initialLayout="@layout/news_widget"
    android:minHeight="40dp"
    android:minWidth="300dp"
    android:previewImage="@android:drawable/ic_menu_add"
    android:resizeMode="horizontal|vertical"
    android:updatePeriodMillis="2700000"
    android:widgetCategory="home_screen">
</appwidget-provider>

But the result I get looks like this, having the widget on minHeight:

enter image description here

So obviously the height of one element in my layout differs a lot to the height of one grid-row on the screen.

What am I doing wrong or what is the canonical approach to solve my problem?

Kelula answered 14/5, 2021 at 8:45 Comment(0)
H
1

minHeight and minWidth are hints and suggestions, not demands. There are hundreds of launchers with home screens, and none are required to honor your desired values or support that small of a height. Your requested sizes are roughly 8:1 aspect ratio; the actual size you got was closer to 3:1.

Your AppWidgetProvider subclass can override onAppWidgetOptionsChanged() and examine the supplied Bundle to get an idea of the actual size of the app widget. It is not guaranteed that this will be called for every home screen, but it's your best shot. There are OPTION_APPWIDGET_ keys on AppWidgetManager that can be in that Bundle. For a Bundle parameter named newOptions, you can try to access:

  • newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
  • newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
  • newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
  • newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)

Those will be values in dp.

From there, you can use AppWidgetManager to send over a new RemoteViews that is perhaps better tailored for the size of the app widget as seen on the home screen.

This old sample project demonstrates this, with an app widget that displays its own size ranges.

Hotchpotch answered 17/5, 2021 at 0:4 Comment(5)
Thansk! What exactly means the min/max value. Does this really help me to resize the widget-content to the correct size? How do I know if I should resize content to min or max?Kelula
Also I am not sure how to change the height of my LinearLayouts. The docs say to use LayoutParams.height before Android 12 but I can't figure out how.Kelula
@progNewbie: "What exactly means the min/max value" -- it means that your app widget has an actual size within the range specified by the min and max values for width and height. "How do I know if I should resize content to min or max?" -- that would be a question for your graphic designer.Hotchpotch
Okay, so one can not really know the exact size :/ Do you know how I can set the size of my RemoteViews?Kelula
@progNewbie: AFAIK, effectively, the RemoteViews itself is akin to a parent container set to match_parent/match_parent for the size, to fill whatever space the RemoteViews is applied to (the app widget, the custom Notification, etc.).Hotchpotch

© 2022 - 2024 — McMap. All rights reserved.