Android (Home screen) Widget - Part 1: Simple widget

    Widgets can be thought of as a small window or controller for an Android app that can be embedded in another application (like the home screen). They can be very useful, allowing users to view or control an app without actually launching it. This is official definition of widget in Android:
Widgets are an essential aspect of home screen customization. You can imagine them as “at-a-glance” views of an app’s most important data and functionality that is accessible right from the user’s home screen.

Types of widget in Android

    Basically, it's can be divided to 4 types of widget in Android:
  • Information widget: display a few crucial information elements that are important to a user and track how that information changes over time. Good examples for information widgets are weather widgets, clock widgets or sports score trackers. Touching information widgets typically launches the associated app and opens a detail view of the widget information. For example: weather widget.
  • Collection widget: collection widgets specialize in displaying multitude elements of the same type, such as a collection of pictures from a gallery app, a collection of articles from a news app or a collection of emails/messages from a communication app. For example: email widget.
  • Control widget: the main purpose of a control widget is to display often used functions that the user can trigger right from the home screen without having to open the app first. For example: change wifi, bluetooth,...state widget.
  • Hybrid widget: While all widgets tend to gravitate towards one of the three types described above, many widgets in reality are hybrids that combine elements of different types. For the purpose of your widget planning, center your widget around one of the base types and add elements of other types if needed. For example: music player widget.

Components of a widget

    There are 3 components of a widget that you must implement:
  • An AppWidgetProviderInfo object: describes the metadata for an app widget, such as the app widget's layout, update frequency, and the AppWidgetProvider class. This should be defined in XML.
  • AppWidgetProvider class implementation: defines the basic methods that allow you to programmatically interface with the App Widget, based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated, enabled, disabled and deleted.
  • View layout: defines the initial layout for the App Widget, defined in XML.
    Additionally, you can implement an app widget configuration Activity. This is an optional Activity that launches when the user adds your app widget and allows him or her to modify app widget settings at create-time. The following sections describe how to set up each of these components.
    Now, please follow these steps to create a very simple widget which open my website when click on it!

Create a layout for the widget

    Providing a simple layout for the widget which only includes a TextView:
res\layout\widget_simple.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txtWidget"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:text="Click to visit my site"
        android:textColor="#ffffff"
        android:textSize="24sp"
        android:textStyle="bold" />


</LinearLayout>
This layout is displayed as a widget on user’s Home screen.

Create an XML file that defines widget properties

    The AppWidgetProviderInfo defines the essential qualities of a widget, such as its minimum layout dimensions, its initial layout resource, how often to update the widget, and (optionally) a configuration Activity to launch at create-time. Define the AppWidgetProviderInfo object in an XML resource using a single <appwidget-provider> element and save it in the project's res/xml/ folder:
widget_provider_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_simple"
    android:minHeight="60dp"
    android:minWidth="100dp"
    android:previewImage="@mipmap/ic_launcher"
    android:resizeMode="horizontal|vertical"
    android:updatePeriodMillis="0"/>
    Take a look at some attributes of <appwidget-provider> above:
  • minHeight and minWidth: Every 60dp means 1 cell in android Home screen. For this example, the widget takes min 1x1 cell(s).
  • initialLayout: reference for the widget layout(that we already created).
  • previewImage: the image that will be shown on android’s widget select screen. We can not draw a layout for preview. We have to set an image. For simple, I use ic_launcher of the application.
  • resizeMode: the configuration for resizing the widget.
  • updatePeriodMillis: the widget’s update method is called when the specified time is reached in a millisecond.

Create a class for the widget lifecycle

    We now need to create a subclass of AppWidgetProvider (it is also a subclass of BroadcastReceiver) so essentially, your widget class is a receiver class. There are some important methods you must/may override:
  • onUpdate(): called to update the app widget at intervals defined by the updatePeriodMillis attribute.
  • onEnabled(): called when an instance the app widget is created for the first time.
  • onDisabled(): called when the last instance of your app widget is deleted from the app widget host.
  • onDeleted(): called every time an app widget is deleted from the host.
  • onAppWidgetOptionsChanged(): called when the widget is first placed and also whenever the widget is resized.
  • onReceive(): called for every broadcast and before each of the above callback methods.
    In this Part 1, I will make a simple widget, so I only override onUpdate() like this:
SimpleWidget.java
package info.devexchanges.simplewidget;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.RemoteViews;

public class SimpleWidget extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // There may be multiple widgets active, so update all of them
        for (int appWidgetId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }

    private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
        // Construct the RemoteViews object
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_simple);

        // Create an Intent object includes my website address
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.devexchanges.info/"));
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

        //handle click event of the TextView (launch browser and go to my website)
        views.setOnClickPendingIntent(R.id.txtWidget, pendingIntent);
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}
    As a receiver class, your must register it to your AndroidManifest.xml:
AndroidManifest.xml
<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".SimpleWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_provider_info"/>
        </receiver>
    </application>

Running the application

    A widget always "attach" with the application. Make sure that you have the default Activity (usually named as MainActivity) when you created a new Android Studio project. Run this application, the widget will be installed and the MainActivity is also launched (with "Hello world"!):
    Move to "WIDGETS" tab on your device, you will see your own widget:
    In order to use it, please hold and drag it to the Home screen:
    And when click the widget:
    Remember that if you uninstall the application, the widget will be removed!

Conclusions

    Now, you're learned about Android widget basic concept and the way to make a simple widget. In Part 2, I will talk about making a Broadcast widget - a widget that have update data when clicked (coming soon!). Further, to deep understanding about widget design and development in Android, please read it's official documents:
    UPDATE: Part 2 now available HERE!

Share


Previous post
« Prev Post
Next post
Next Post »