Skip to content

App Widget

XML fossil

Example: Click to launch the app intent with custom extra

<ImageView
android:id="@+id/account_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/outline_account_circle_24" />
<Button
android:id="@+id/account_button"
android:text="Account"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
val accountIntent = Intent(context, MainActivity::class.java).apply {
putExtra(WidgetExtra.ACTION.name, "account") // WidgetExtra is a custom enum
}
val accountPendingIntent = PendingIntent.getActivity(
context, appWidgetId, accountIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
RemoteViews(context.packageName, R.layout.diary_widget).apply{
setOnClickPendingIntent(R.id.account_button, accountPendingIntent)
}

Required RemoteViewsService with RemoteViewsFactory Example: Get data from local sqlite via a object and inject them into ListView

Remember to add the service config to manifest

class MyWidgetService : RemoteViewsService() {
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
return DiariesListViewFactory(applicationContext)
}
}
class DiariesListViewFactory(private val context: Context) : RemoteViewsService.RemoteViewsFactory {
private val diaries = mutableListOf<Diary>()
override fun onCreate() {
DatabaseRepo.loadDiaries(context)
diaries.clear()
diaries.addAll(DatabaseRepo.diaries)
}
override fun onDataSetChanged() {
}
override fun onDestroy() {
diaries.clear()
}
override fun getCount(): Int = diaries.size
override fun getViewAt(position: Int): RemoteViews {
val item = diaries[position]
val views = RemoteViews(context.packageName, R.layout.diary_item).apply {
setTextViewText(R.id.item_title, item.title)
setTextViewText(R.id.item_author, item.uploadUserName)
val fillInIntent = Intent().apply {
putExtra(WidgetExtra.ID.name, item.id)
}
setOnClickFillInIntent(R.id.item_root, fillInIntent)
}
return views
}
override fun getLoadingView(): RemoteViews? = null
override fun getViewTypeCount(): Int = 1
override fun getItemId(position: Int): Long = position.toLong()
override fun hasStableIds(): Boolean = true
}

Bind service to ListView

val intent = Intent(context, MyWidgetService::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
}
val views = RemoteViews(context.packageName, R.layout.diary_widget).apply {
setRemoteAdapter(R.id.diaries_listview, intent)
}