앱의 가장 중요한 데이터와 기능을 사용자의 홈 화면에서 한 눈에 볼 수 있으며 바로 엑세스 가능하도록 만든 뷰
위젯도 일반적인 앱처럼 돌아간다고 생각할 수 있겠지만, 액티비티의 모음으로 이루어진 일반적인 앱들과는 다소 차이가 있다.
class ExampleAppWidgetProvider : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// Perform this loop procedure for each App Widget that belongs to this provider
appWidgetIds.forEach { appWidgetId ->
// Create an Intent to launch ExampleActivity
val pendingIntent: PendingIntent = Intent(context, ExampleActivity::class.java)
.let { intent ->
PendingIntent.getActivity(context, 0, intent, 0)
}
// Get the layout for the App Widget and attach an on-click listener
// to the button
val views: RemoteViews = RemoteViews(
context.packageName,
R.layout.appwidget_provider_layout
).apply {
setOnClickPendingIntent(R.id.button, pendingIntent)
}
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
}
위젯도 크기를 막 설정하면 안이쁘게 나와서 보기 좀 그렇다.
공식 문서에서는 셀 개수 당 크기가 다음과 같다고 한다.
근데 적용해보니까 실제로 잘 안돼서 조금 당황했다..
어떤 사람은 (셀 개수 * 74) - 2으로 하니까 잘 됐다고 하는데, 난 결국 노가다의 길을 걷고야 말았다...
난 위젯이 어떤 행동에 의해 다른 뷰로 바뀌기도 하는 등의 기능을 기대하고 있었다.
그런데, 생각보다 이게 어려웠다.
AppWidgetProvider에 PendingIntent를 통해서 연결해주는 액티비티가 있어서 처음에는 액티비티를 여러개 생성하였다.
이후 그때그때 위젯 화면을 달리해주고 싶을 때마다 PendingIntent를 다른 액티비티에 새로 연결해주자는 생각이었다.
근데 이게 생각처럼 되지도 않을 뿐더러, 위젯은 가볍게 만들어야 하는데 뷰가 너무 중구난방으로 바뀌는게 아닌가 하는 생각도 들었다.
사실 위젯의 목적이 간단한 정보 전달과 기능 제공인데 말이다.
그래서, 뷰 변화도 정말 간단히 바꿔주어 위젯의 제 기능에 충실하고자 하였다.
그렇다면 뷰를 어떻게 변화시켰느냐??
정말 원시적인 방법이면서도 안좋은 방법이라고 생각하긴 하지만, visibility 속성을 이용하기로 하였다.
기존 레이아웃은 VISIBLE 상태로 놓고, 후에 나타나게 하고 싶은 레이아웃을 INVISIBLE이나 GONE으로 해놨다가 이벤트가 발생하면 기존 것을 GONE으로 바꿔주고 나타나게 하고 싶은 레이아웃을 VISIBLE로 바꿔주었다.
위젯 구현 시에는 RemoteView를 통해 뷰를 끌어오기에 해당 RemoteView의 내장 함수인 setViewVisibility(int viewId, int visibility)를 사용하면 쉽게 바꿔줄 수 있다.