package com.example.myapp.widget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.widget.RemoteViews
import com.example.myapp.R
import com.example.myapp.ui.MainActivity
class PostsWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
appWidgetIds.forEach { appWidgetId ->
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
override fun onEnabled(context: Context) {
// First widget added - perform initial setup
}
override fun onDisabled(context: Context) {
// Last widget removed - cleanup
}
companion object {
fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
// Create an Intent to launch MainActivity
val pendingIntent: PendingIntent = Intent(context, MainActivity::class.java)
.let { intent ->
PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
)
}
// Create refresh intent
val refreshIntent = Intent(context, PostsWidget::class.java).apply {
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(appWidgetId))
}
val refreshPendingIntent = PendingIntent.getBroadcast(
context,
0,
refreshIntent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val views = RemoteViews(context.packageName, R.layout.widget_posts).apply {
setOnClickPendingIntent(R.id.widget_container, pendingIntent)
setOnClickPendingIntent(R.id.refresh_button, refreshPendingIntent)
// Set collection adapter for list
val listIntent = Intent(context, PostsWidgetService::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
}
setRemoteAdapter(R.id.widget_list, listIntent)
// Set empty view
setEmptyView(R.id.widget_list, R.id.empty_view)
}
appWidgetManager.updateAppWidget(appWidgetId, views)
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_list)
}
}
}
package com.example.myapp.widget
import android.content.Context
import android.content.Intent
import android.widget.RemoteViews
import android.widget.RemoteViewsService
import com.example.myapp.R
import com.example.myapp.data.repository.PostRepository
class PostsWidgetService : RemoteViewsService() {
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
return PostsRemoteViewsFactory(this.applicationContext)
}
}
class PostsRemoteViewsFactory(
private val context: Context
) : RemoteViewsService.RemoteViewsFactory {
private var posts: List<Post> = emptyList()
override fun onCreate() {
// Setup
}
override fun onDataSetChanged() {
// Fetch data - this runs on UI thread but can be synchronous
// In real app, fetch from repository
posts = getDummyPosts()
}
override fun onDestroy() {
posts = emptyList()
}
override fun getCount(): Int = posts.size
override fun getViewAt(position: Int): RemoteViews {
val post = posts[position]
return RemoteViews(context.packageName, R.layout.widget_post_item).apply {
setTextViewText(R.id.post_title, post.title)
setTextViewText(R.id.post_author, post.author)
// Set click intent
val fillInIntent = Intent().apply {
putExtra("post_id", post.id)
}
setOnClickFillInIntent(R.id.post_item, fillInIntent)
}
}
override fun getLoadingView(): RemoteViews? = null
override fun getViewTypeCount(): Int = 1
override fun getItemId(position: Int): Long = posts[position].id.toLong()
override fun hasStableIds(): Boolean = true
private fun getDummyPosts(): List<Post> {
return listOf(
Post(1, "Post 1", "Body", "Author 1", 0L),
Post(2, "Post 2", "Body", "Author 2", 0L)
)
}
}