Correctly styling Android Home Widget size

Viewed 298

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?

1 Answers

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.

Related