[GNU BOB] 3. JetPack glance를 이용해서 위젯 구현하기
https://github.com/ikhyeons/gnuBobWidget
그누밥 프로젝트에서 위젯의 프론트를 담당할 부분을 제작한다.
안드로이드 위젯을 제작하기 위하여 AndroidStudio를 사용하여 제작하였으며, AndroidStudio에서 기본적으로 제공하는 new Project의 Empty Activity에서 시작해서 구현하였다.
1. JetPack glance 개발 초기 세팅 하기
Empty Activity에서 새 프로젝트를 생성하면, 아래 사진과 같은 형식의 폴더 구조를 가지게 된다.
위젯을 제작하는 데에 있어서 아래 파일을 집중적으로 다룬다.
AndroidManifest.xml - 위젯의 진입점 또는 위젯이 모바일기기에서 동작할 때의 허가 같은 것을 조절할 수 있다.
ui.theme 패키지 - 해당 프로젝트에서 사용하는 디자인 CSS같은 것들을 미리 지정해 놓을 수 있다.
MainActivity.kt - 앱을 실행시켰을 때의 진입점으로 사용되며, AndroidManifest.xml에서 activity의 android:name으로 진입점을 수정할 수 있다.
res - 프로그램에서 사용될 리소스들을 모아놓는다. 상수 또는 프로그램에서 수정할 일이 크게 없는 문자열과 데이터와 같은 리소스들이 들어간다.
Gradle Scripts - npm의 pakage.js처럼 dependancy들을 관리할 수 있다. 해당 목록에 디펜던시를 추가하고 세이브하면 android studio에서 자동으로 다운하여 적용한다.
먼저. gladle에 Glance를 추가하여 위젯을 개발할 수 있도록 디펜더시를 추가하였다.
또한 http통신으로 ajax데이터를 내가만든 node서버에서 받아와야 하기 때문에 okhttp라는 라이브러리 또한 설치하였다.
implementation ("androidx.glance:glance-appwidget:1.0.0")
implementation ("androidx.glance:glance-material:1.0.0")
implementation ("androidx.glance:glance-material3:1.0.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
2. 구현하기
나는 최종 목적이 위젯이기 때문에 위젯을 어떻게 만드는지에 대하여 검색하였다. 그러던 중에 JetPack Compose라는 라이브러리를 찾았고, 해당 라이브러리에서 제공하는 Glance를 이용하여 위젯을 구현하였다.
Glance로 위젯을 제작하기 위해서 GlanceAppWidgetReceiver를 진입점으로 설정하고 실제 위젯을 등록해야 한다.
//소스 파일에 glance 리시버 생성.
package com.example.basicscodelab.glance
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import com.example.basicscodelab.MyAppWidget
class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
// Let MyAppWidgetReceiver know which GlanceAppWidget to use
override val glanceAppWidget: GlanceAppWidget = MyAppWidget()
}
glance의 리시버를 생성하고
AndroidManifest.xml에 위젯의 진입점을 receiver에 등록한다.
<receiver android:name=".MyAppWidgetReceiver"android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"android:resource="@xml/new_app_widget_info" />
</receiver>
이러면 위젯을 생성하였을 때 내가 glance로 생성한 위젯이 생성된다.
이후에 MyAppWidget을 수정하여 위젯을 구현할 수 있다.
찾아본 kotlin android 강의에서는 xml을 이용하여 버튼, 박스들을 생성하고 해당 엘리먼트를 타겟으로 css를 지정하는 방식으로 구현을 하고 있었다. 그러다 검색을 계속 해 보니 이를 jetPack을 이용해서 구현하는 것을 발견하여 이 방식을 적용하기로 하였다. 이 방식은 마치 React의 컴포넌트를 조립하는 것과 매우 흡사하였기 때문에 간단하게 적용할 수 있었다.
2.1 컴포넌트 생성.
class MyAppWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
// create your AppWidget here
MyContent()
}
}
}
@Composableprivate fun MyContent() {}
위의 @Composable 애노테이션을 이용하여 리액트에서의 컴포넌트와 같은 개념을 생성할 수 있다. 이후 해당 컴포넌트의 body에서 라이브러리에 내장된 엘리멘트들을 가져와 렌더링 한다. 아래 예는 row형의 엘리멘트를 렌더링 하는 것.
class MyAppWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
// create your AppWidget here
MyContent()
}
}
}
@Composableprivate fun MyContent() {
Row() {
//row의 body안에 다른 element를 또 위치하여 복잡한 구성을 구현할 수 있다.
}
}
2.2 css 수정
이후 modifier를 이용하여 해당 엘리먼트의 스타일을 수정할 수 있으며, 몇몇 스타일들은 해당 엘리멘트에 내장된 인수를 받아서 스타일한다.
@Composableprivate fun MyContent() {
Row(
modifier = GlanceModifier
.clickable({cOrG.value=i})
.background(Color(204, 153, 255)) // 여기에 원하는 배경색 설정
.padding(8.dp)
.cornerRadius(16.dp)
) {
Text(
text = "$i",
style = TextStyle(textAlign = TextAlign.Center)
)
}
}
2.3 상태관리
상태에 따른 데이터를 바꾸고 싶을 땐 remember를 이용하여 변동되는 상태를 선언하고,
이를 통하여 선언된 상태는 변경 될 때 마다 react처럼 자동으로 화면이 갱신된다.
//선언은 이렇게
var cOrG = remember {mutableStateOf("가좌캠")}
3. 배포
android studio의 build → Generate Signed Bundle or APK를 이용하여 배포판의 apk파일을 생성할 수 있다. 이렇게 만든 gnu_bob 프로젝트를 우리학교 학생들이 사용할 수 있도록 에브리타임에 업로드하였다.
완성 화면 사진
2024. 2. 18 26 0