💡 위젯 구성
- AppWidgetProvidernfo - 위젯의 메타데이터 설명
- AppWidgetProvider - 프로그래밍을 통한 기본 메서드 정의
- view (xml) - 초기 레이아웃 정의
💡 AppWidgetProvider
AppWidgetProvider 클래스는 BroadcastReceiver 를 확장한 클래스로, 위젯과 관련된 이벤트 브로드캐스트를 수신한다.
- onUpdate(): 위젯을 업데이트하기 위해 호출. 이벤트 핸들러 등 필수 설정을 수행해야 한다.
리스트뷰가 포함된 위젯을 만들려면 onUpdate() 메서드 내에 setRemoteAdapter() 를 호출함으로써, 데이터를 불러와 리스트뷰에 바인딩시킬 수 있도록 구현한다.
class NewAppWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
super.onUpdate(context, appWidgetManager, appWidgetIds)
}
}
}
internal fun updateAppWidget(
context: Context,
appWidgetManager : AppWidgetManager,
appWidgetId: Int
) {
val widgetText = context.getString(R.string.appwidget_text)
val intent = Intent(context, MyWidgetService::class.java)
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.new_app_widget).apply {
setTextViewText(R.id.widget_title, widgetText)
setRemoteAdapter(R.id.widget_list, intent)
}
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}
AndroidManifest.xml
<receiver android:name="ExampleAppWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
제공자 클래스는 AndroidManifest.xml <receiver> 내에 정의되어야 하며, <intent-filter> 속성을 포함시키므로 브로드캐스트를 허용하도록 지정한다.
💡 RemoteViewsService
위젯 레이아웃은 늘 RemoteViews를 기반으로 한다. 그렇기에 지원되는 레이아웃과 뷰에 제한이 있다. 그래서 이번엔 ListView를 사용해 위젯을 구성해 보는 방법을 알아보겠다.
앱 위젯에서 리스트뷰를 사용하려면 RemoteViewsService를 사용하여 원격 데이터를 불러와야 한다. 컬렉션에 데이터를 표시하려면 Adapter를 사용하여 화면에 데이터를 바인딩해야 하는데, 앱 위젯 context에서 Adapter는 Adapter를 감싸고 있는 RemoteViewsFactory로 대체된다.
이때 RemoteViewsService는 원격 어댑터가 RemoteViews 객체를 요청할 수 있는 서비스이다.
class MyWidgetService : RemoteViewsService() {
override fun onGetViewFactory(p0: Intent): RemoteViewsFactory {
return MyRemoteViewsFactory(this.applicationContext)
}
}
RemoteViewsFactory 클래스는 리스트뷰 항목에 대한 데이터를 위젯에 제공한다. 즉 데이터를 원격으로 리스트뷰에 연결하는 어댑터 역할을 하는 것이다.
class MyRemoteViewsFactory(
private val context: Context
): RemoteViewsService.RemoteViewsFactory {
private lateinit var widgetItems: List<String>
override fun onCreate() {
widgetItems = listOf("1", "2", "3")
}
override fun getViewAt(p0: Int): RemoteViews {
val remoteViews = RemoteViews(context.packageName, R.layout.widget_list_item).apply {
setTextViewText(R.id.widget_item_title, widgetItems[p0])
}
return remoteViews
}
/** implement method */
}
처음 Factory 생성 시, 시스템이 onCreate() 를 생성한다. 이때 데이터 아이템 개체 초기화 및 데이터 연결에 대한 부분을 수행할 수 있다. 위젯은 여기서 초기화된 배열의 인덱스에 접근하여 데이터를 표시한다.
AndroidManifest.xml
<service android:name="MyWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS">
</service>
manifest 파일에 해당 서비스를 선언해준다. BIND_REMOTEVIEWS 권한을 사용하여 다른 애플리케이션이 위젯 데이터에 접근하는 것을 방지할 수 있다.
여기까지 하면, 위젯을 띄웠을 때 임의로 넣은 데이터가 리스트뷰에 표시되는 것을 볼 수가 있다.
'Android' 카테고리의 다른 글
[Android] 포그라운드 서비스 사용 (Foreground Service) (1) | 2024.09.24 |
---|---|
[Android] Branch.io SDK 연동 / 딥링크 사용법 / 커스텀 이벤트 트래킹하기 (0) | 2024.01.16 |
[Android] 딥링크 / URI Scheme 방식 사용하기 (0) | 2023.04.04 |
[Android] Naver Map Api로 네이버 지도 사용하기 (0) | 2022.04.07 |