Android Widget Development: How to Meet Custom Requirements
IT copywriter
Reading time:
Today we can hardly imagine an Android device without widgets. Google introduced mobile app widgets for Android 1.5 and reworked them a lot for Android 3.0 and 3.1. Widgets serve as a way to quickly access app information, remotely manage an app, and can also be personalized according to individual user requirements.
The simplicity and popularity of widgets has led to an increase in the demand for the development of customized widgets for Android apps. However, widget implementation is not as easy as it may seem.
In general, we can divide Android widgets into three main categories:
- Information widgets
These display the latest updated information about the app state. Weather, time and currency quotation widgets all belong to this category. - Collection widgets
These present the collection of similar information. For example, a collection of emails, articles or daily tasks. - Control widgets
These provide quick and easy access to app functions that are most important for the user. It means that the user can manage the app from the home screen without opening it.
The majority of widgets belong to a hybrid type. They combine the elements of all types into one. However this doesn’t influence the number of complications that may arise in the development process.
We are going to describe widget implementation according to client requirements using an example of a widget we made for one of our regular customers recently. We hope this will help you overcome some potential issues.
The Challenge
Being one of the largest internet providers in Russia, Novotelecom turned to Azoft to develop an application «Private Office». The app was intended to give business customers access to their account using the app. Apart from access it would also allow them to top up their balance, delay a payment, pick new options and more.
The important task within the project scope was to implement a widget for the app.
To build the widget we had to meet the following requirements:
- The widget should display the current balance and the time of last update
- There should be 2 buttons: to move to the settings screen and forced update by a user request
- The widget needed a configuration screen with features that allowed users to set the time of balance update and change the widget transparency
Handling the task, we had a complication with proper setting of widget functions according to different Android devices and screen orientations.
Android Widget Implementation
In order to build an Android widget you should always use the following tools:
- Metadata file
It describes the general widget settings and includes all the widget components, such as a layout file and a configuration class - WidgetProvider class
This provides methods of handling widget events, such as adding a widget to the screen, resizing, removing from the screen etc - Layout file
This displays how a widget is going to look like on the home screen - Widget settings screen
This appears right after we put the widget on the home screen
The widget implementation details are described at developer.android.com. Here, we are talking about the most sensitive issues of widget display.
When we started to implement the first widget prototype, we faced two problems.
The first problem was the size of the cells on the screen. The cells have different dimensions for portrait and landscape screen orientations. It implies that a cell is stretched upward and can change the size when a screen changes from portrait to landscape. For this reason, a widget occupies all the available area within a landscape orientation. This happened with our widget when we made the first prototype.
The second problem relates to the process of widget implementation. We work over the widget within another process, that’s why there is only a RemoteViews class for displaying the widget. Just a few classes of View are available for RemoteViews and even their extended classes are forbidden. As a result, we cannot extend ImageView and calculate the background proportions within the class.
Thus, we concluded that we couldn’t create a widget using the classic way. We then began to look for a solution of building the widget in accordance with the required design.
- Given that the background has rounded edges, we had to use a png or shape. We chose png.
The design required locating the widget horizontally, but the cells of Android screens are stretched upward. To keep the widget proportions, we strictly set the height and width for the layout. To control the size of the widget for all the possible devices, we had to create separate layouts for several resolutions.
- The background transparency changes dynamically and depends on the widget settings. In order to change the RemoteViews, a widget has methods like setInt, setFloat, setBitmap and others. We could call it with parameters such as an identifier View, a method name and a parameter for this method.
- The next step for setting a background was the method setBitmap:
views.setBitmap(R.id.iv_widget_background, "setImageBitmap", newBitmap);
To set the transparency we changed the alpha pixel-by-pixel in the Bitmap and afterwards we put it in the background.
The Work with Alpha
From the early beginning, we simply changed the png transparency to the one we needed. In other words, we set alpha equals 1 to the whole picture and transparent angles as well. Unfortunately, the angles became black.
pixel = pixels[index]; A = alpha; R = Color.red(pixel); G = Color.green(pixel); B = Color.blue(pixel); pixels[index] = Color.argb(A,R,G,B);
Then we decided to change the alpha only for non-transparent pixels. However the angles became sharp, with pixels sticking out over the edges, because smooth angles in a png are achieved using pixels with a different alpha.
pixel = pixels[index]; A = Color.alpha(pixel); if (A > 0) { A = alpha; } R = Color.red(pixel); G = Color.green(pixel); B = Color.blue(pixel); pixels[index] = Color.argb(A,R,G,B);
Then we tried to make another improvement. We changed the alpha only for the pixels that were more visible than the current alpha. It helped us to keep the alpha of more transparent pixels that provides the smooth angles of the widget.
pixel = pixels[index]; A = Color.alpha(pixel); if (A > alpha) { A = alpha; } R = Color.red(pixel); G = Color.green(pixel); B = Color.blue(pixel); pixels[index] = Color.argb(A,R,G,B);
Conclusions
After several attempts to change the transparency with the alpha, we finally got the desirable widget view:
Considering that cells on Android screens are stretched upward, the widget took up more screen space, than his visible part. It means that a user can see only the particular picture of the widget and cannot distinguish where the widget ends.
Of course, the described implementation method has some limitations. We had to make a separate layout for each widget size in order to maintain the native view of the widget. Nevertheless, our solution helps to overcome these shortfalls of Android widgets and accomplish the task.
Comments