Making an Android Widget

SC
4 min readJan 11, 2019

--

In this tutorial, you will learn how to create an Android Widget that is a homescreen memo and give it a custom typeface.

What is a widget?

Widgets are smaller views of an application that can be placed on the home screen for faster access.

A home screen memo widget

Making a Widget

In the Android Studio menu, select File -> New -> Widget -> App Widget. This will open up a configuration screen.

  1. On this screen, name your widget MemoWidget under the Class Name prompt.
  2. Widgets can be placed on the home screen or the lock screen. However, it can only be placed on the lock screen (called keyguard) for Android versions lower than 5.0.
  3. Make your widget Not Resizable for a static memo size.
  4. Determine the size of your widget with the Minimum Width and Minimum Height prompts.
  5. Check Configuration Screen if you want a configuration activity for your widget. You will need to check this if you want to change the appearance of the widget based on user input. To follow this tutorial, check Configuration Screen, since we are displaying user inputted text on a memo.

When you select finish, five things will be created for you: a Java class for the widget, a Java class for the configuration activity, a xml layout for the widget, a xml layout for the configuration activity, and a xml file for the widget details.

Making the Widget Layout

Open the memo_widget.xml, which can be found under app -> res -> layout in the project menu.

Go to the text of the layout. We’re going to change the TextView to an ImageView and change some of the settings, as shown below:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:padding="@dimen/widget_margin">


<ImageView
android:id="@+id/appwidget_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/memo1_4"

android:padding="8dp"
android:paddingEnd="8dp"
android:paddingStart="100dp"
android:contentDescription="@string/appwidget_text"/>


</RelativeLayout>

The padding is necessary for the specific background image used because I wanted the text to begin not flush against the left side. If you want your text against the left side, remove the padding.

The background should be set to a drawable that you want to be the background of your memo.

Finished widget layout

Custom Typeface on Memo

To create a custom typeface, you must first create an assets folder under the app folder in the Project window. Next, in the assets folder, create a directory called fonts. Then copy paste the ttf file of your font into the fonts folder.

For widgets, the only way to use a custom typeface is to draw the text onto a canvas with a DynamicLayout.

Under the MemoWidget class, delete the view.setTextViewText(…) from the updateAppWidget method.

private static DynamicLayout textLayout;static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {

CharSequence widgetText = MemoWidgetConfigureActivity.loadTitlePref(context, appWidgetId);
String widgetTextString = widgetText.toString();
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.memo_widget);

Bitmap bitmap = Bitmap.createBitmap(168, 84, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
TextPaint textPaint = new TextPaint();
Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/indieflower.ttf");

textPaint.setTypeface(typeface);
textPaint.setAntiAlias(true);
textPaint.setTextSize(19);
textLayout = new DynamicLayout(widgetTextString, textPaint, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

int textX = 0;
int textY = 0;

canvas.translate(textX,textY);
textLayout.draw(canvas);

views.setImageViewBitmap(R.id.appwidget_text, bitmap);
appWidgetManager.updateAppWidget(appWidgetId, views);
}

Create a private static DynamicLayout called textLayout. Create a string variable called widgetTextString, and set it to widgetText.toString. This will be used later as an argument for the creation of the DynamicLayout.

We will create a Bitmap for the canvas, the TextPaint, then a Typeface. Next we will set the TextPaint to our Typeface. AntiAlias must be true to smooth the text. We will also set the text size of the TextPaint. Initialize the textLayout using the user-inputted text and the textPaint we created.

We will create an x and y value for the canvas location. We will translate the canvas to those values, then draw the text onto the canvas. Finally we will set the ImageView to our bitmap.

When the code is run, you will have a working memo widget with a custom font!

--

--