Android 커스텀 레이아웃으로 앱 위젯 만들기
Android App widget
App Widgets 이란?
아래 사진과 같이 런처 앱에서 설치된 앱의 기능을 사용할 수 있도록 해줍니다.
Widget을 만드는 방법
아래의 안드로이드 공식 문서를 통해 기본적인 제작 방법을 학습할 수 있습니다.
Create app widget - Android developers
App widget processing flow
앱 위젯을 처리하는 흐름
- 핵심
- BroadcastReceiver로 위젯 업데이트 처리
- RemoteViews로 위젯 UI를 처리
위젯 제작 과정
아래는 예시 입니다. 전체 예제 코드
res
디렉토리 내에 위젯 관련 파일을 담을 적절한 디렉토리를 만듭니다.res/layout
디렉토리 내에 위젯 레이아웃 파일view_widget
을 만들고 레이아웃을 제작합니다.- 만든 디렉토리 내에
nine-widget-info.xml
라는 이름의 리소스 파일을 만들고 아래와 같이 작성합니다.
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.lifedawn.bestweather.widget.ConfigureWidgetActivity" // 위젯을 런처에 생성하고자 할때 사용하는 위젯 설정 화면, 생성이 필수는 아님
android:initialLayout="@layout/view_widget" // 위젯 레이아웃
android:minWidth="@dimen/ninthWidgetWidth"
android:minHeight="@dimen/ninthWidgetHeight"
android:minResizeWidth="@dimen/ninthWidgetWidth"
android:minResizeHeight="@dimen/ninthWidgetHeight"
android:previewImage="@drawable/widget_preview_9" // 런처 앱에서 위젯 추가 시 나오는 이미지
android:resizeMode="vertical|horizontal" // 위젯 크기 조정 가능한 모드, 수평/수직 모두 조정 할 수 있도록 하겠다는 의미
android:updatePeriodMillis="0" // 위젯 업데이트 주기, 0이면 자동 업데이트 하지 않고 수동 업데이트로만 가능
android:widgetCategory="home_screen" // 홈 화면에 위젯을 보여준다는 의미, 안드로이드 5 부터는 이것만 가능
/>
- 위젯 업데이트와 같은 처리는
BroadcastReceiver
를 통해서 진행하기 때문에 관련 로직을 처리할NinthWidgetProvider
클래스를 만들고 내용을 작성합니다. AndroidManifest.xml
내application
태그 내에 앱 위젯 내용을 추가합니다.
<receiver
android:name=".widget.widgetprovider.NinthWidgetProvider"
android:exported="true"
android:label="@string/ninthWidgetLabel">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> // 필수
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider" // 필수
android:resource="@xml/ninth_widget_info" />
</receiver>
- 완료
위젯을 런처 앱에 추가하는 경우에 사용자가 위젯에 대해 부가적인 설정이 가능하도록 하고자 하는 경우에는 위의 ConfigureWidgetActivity
를 생성하면 됩니다.
런처 앱에서 위젯 추가 버튼을 클릭시 이 액티비티
가 나오고 관련 설정이 가능해집니다.
위젯 레이아웃 제작의 한계점
앱 위젯은 해당 앱이 다른 프로세스인 런처 앱 상에서
RemoteViews
라는 View로 원격으로 레이아웃을 보여주는 방식이기 때문에, 개발자가 원하는 대로 레이아웃을 제작하는 것이 어렵다는 한계점이 있습니다.
- 앱 위젯에 사용 가능한 레이아웃 및 위젯
- AdapterViewFlipper
- FrameLayout
- GridLayout
- GridView
- LinearLayout
- ListView
- RelativeLayout
- StackView
- ViewFlipper
- AnalogClock
- Button
- Chronometer
- ImageButton
- ImageView
- ProgressBar
- TextClock
- TextView
- 안드로이드 12 부터 가능
- CheckBox
- RadioButton
- RadioGroup
- Switch
한계점을 벗어나, 원하는 레이아웃을 제작하는 방법
RemoteViews
에서 사용가능한 위젯과 레이아웃으로는 아래의 위젯 제작이 매우 어렵습니다.
Bitmap으로 만들어 ImageView에 지정하여 해결
- 작업 과정
- 동적으로 레이아웃 제작
RelativeLayout
생성- 최상위 view
LinearLayout
생성RelativeLayout
의 자식 View- 시간, 날씨 아이콘(맑음, 비 등)의 정보 표시
nine-widget-info.xml
에서 설정했던 위젯의 width, height정보를 pixel 값으로 변환- 최상위 view의 width, height를 변환한 pixel 값으로 설정
Bitmap viewBmp = rootLayout.getDrawingCache()
remoteViews.setImageViewBitmap(R.id.bitmapValuesView, viewBmp);
- 완료
- 동적으로 레이아웃 제작
결과
아래의 사진은 ImageView를 사용하여 만든 위젯과, RemoteViews에서 사용가능한 뷰와 레이아웃으로 만든 위젯의 레이아웃 계층도를 보여줍니다.
Bitmap으로 처리한 위젯이 제대로 동작하고 있는 것을 확인할 수 있습니다.