Widgets are an important feature of home screen customization. You can consider them an “at-a-glance” view of an app’s most important data and functionality that is available right from the user’s home screen. Widgets can be moved across the home screen, and can be resized based on the information on the widget.
There are four types of widgets:
Information widgets
Collection widgets
Control widgets
Hybrid widgets
These display vital information from an app that is easily visible without actually accessing the app’s main UI and track information change over time. We can open the associated app to view more information by touching the information widget.
Examples: Weather widgets, clock widgets, etc.
Collection widgets specialize in displaying a multitude of elements of the same type. Collection widgets can scroll vertically. We can browse among the collections and then open an element to see a detailed view. For example, we can view pictures from the gallery or we can show news article collection widgets that will show all news/articles.
These can be used to turn on/off some system settings like wifi. These widgets allow us to easily use tools like wifi, Bluetooth, etc.
As the name suggests these widgets are a hybrid of different widgets which make them different from widgets which are specific to one type.
Widgets come with many advantages but there are some limitations. Some of them are as follows.
Gesture: With widgets we have limited gesture support for navigation as compared to the app, since widgets have to be present on the home screen which may have some gesture functions already present. Horizontally shifting widgets is not possible since that is used in the home screen for navigation. Widgets can only use gestures like touch and vertical swipe.
Element: We cannot use some UI elements that require specific gesture support since gesture support is limited.
Widget content: We need to provide content in widgets that are used frequently. Widgets are like information snacks or teasers. They should contain information to attract the user to the application but the full-screen app should always contain more information than widgets.
Widget navigation: Widgets are for quick, frequently usable features of an app. To enable more such quick use we can provide navigation links that will extend the widget functionality and give users more options on the home screen. We can use these for navigation:
Generative functions: Generative functions allow the user to create new content for an app, like a new document or a new message.
Open application at the top level: By clicking on the information element we get to the lower level detail screen which provides access to the top level of the app.
Widget resizing: Resizing allows users to change the height and width of a widget in the constraints of the home screen placement grid. The advantage is that we can decide whether we want to make our widget freely resizable or if we want to constrain it to horizontal or vertical size changes. If our widgets are inherently fixed size then we don’t need to use resizing.
Example:
Manifest: Declare an app widget in the manifest file. Add AppWidgetProvider object in the AndroidManifest.xml file.
1 2 3 4 5 6
<receiver android:name=".NewAppWidget"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" / </intent-filter <meta-data android:name="android.appwidget.provider" android:resource="@xml/new_app_widget_info" /> </receiver>
Now create a new folder, XML, under the res folder. First, right-click on your XML folder and Go to New >select Layout Resource File and give it any name.
new_app_widget_info.xml
1 2 3 4 5 6 7 8 9 10 11
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:configure="com.sehar.appwidgets.NewAppWidgetConfigureActivity" android:initialKeyguardLayout="@layout/new_app_widget" android:initialLayout="@layout/new_app_widget" android:minWidth="110dp" android:minHeight="110dp" android:previewImage="@drawable/example_appwidget_preview" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="86400000" android:widgetCategory="home_screen"> </appwidget-provider>
new_app_widget.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#90ffffff" android:orientation="vertical" android:padding="@dimen/widget_margin"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/imbook" android:layout_width="60dp" android:layout_height="60dp" android:layout_alignParentTop="true" android:contentDescription="TODO" app:srcCompat="@drawable/book" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:orientation="vertical"> <TextView android:id="@+id/tb1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="@string/title" /> <TextView android:id="@+id/tv2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="TextView" android:textSize="16sp" android:textStyle="bold" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:id="@+id/tv3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:clickable="true" android:text="TextView" /> <ImageView android:id="@+id/imref" android:layout_width="50dp" android:layout_height="30dp" app:srcCompat="@drawable/refrese" /> </LinearLayout> </LinearLayout>
new_app_widget_configure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
<?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="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:text="@string/configure" /> <EditText android:id="@+id/appwidget_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text" /> <Button android:id="@+id/add_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/add_widget" /> </LinearLayout>
activity_main.xml
1 2 3 4 5 6 7 8
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"/>
NewAppWidget.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.example.appwidgets;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
public class NewAppWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = NewAppWidgetConfigureActivity.loadTitlePref(context, appWidgetId);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@Override
public void onUpdate(Context mcontext, AppWidgetManager mappWidgetManager, int[] appWidgetIds) { //This method responsible for Updating of widgets.
for (int appWidgetId: appWidgetIds) {
updateAppWidget(mcontext, mappWidgetManager, appWidgetId);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
for (int appWidgetId: appWidgetIds) {
NewAppWidgetConfigureActivity.deleteTitlePref(context, appWidgetId);
}
}
@Override
public void onEnabled(Context context) {}
@Override
public void onDisabled(Context context) {}
}
NewAppWidgetConfigureActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.example.appwidgets;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class NewAppWidgetConfigureActivity extends Activity {
private static final String PREFS_NAME = "com.example.appwidgets.NewAppWidget";
private static final String PREF_PREFIX_KEY = "appwidget_";
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
EditText mAppWidgetText;
View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
final Context context = NewAppWidgetConfigureActivity.this;
String widgetText = mAppWidgetText.getText()
.toString();
saveTitlePref(context, mAppWidgetId, widgetText);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
NewAppWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
};
public NewAppWidgetConfigureActivity() {
super();
}
static void saveTitlePref(Context mcontext, int appWidgetId, String text) {
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0)
.edit();
prefs.putString(PREF_PREFIX_KEY + appWidgetId, text);
prefs.apply();
}
static String loadTitlePref(Context context, int appWidgetId) {
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
String titleValue = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null);
if (titleValue != null) {
return titleValue;
} else {
return context.getString(R.string.appwidget_text);
}
}
static void deleteTitlePref(Context context, int appWidgetId) {
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0)
.edit();
prefs.remove(PREF_PREFIX_KEY + appWidgetId);
prefs.apply();
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Set the result to CANCELED. This will cause the widget host to cancel
setResult(RESULT_CANCELED);
setContentView(R.layout.new_app_widget_configure);
mAppWidgetText = (EditText) findViewById(R.id.appwidget_text);
findViewById(R.id.add_button)
.setOnClickListener(mOnClickListener);
// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
return;
}
mAppWidgetText.setText(loadTitlePref(NewAppWidgetConfigureActivity.this, mAppWidgetId));
}
}
MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.appwidgets;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
OUTPUT:-