제목에서 본 기능은 갤럭시 유저라면 삼성 브라우저를 통해 익숙한 기능일 것이다.
다만, 이 기능을 앱의 웹뷰에서 적용해야하는지는 기획에 따라 달라지겠지만
나는 이번에 Compose 공부도 하는 겸 추가해보았다.
본격적으로 글을 시작하기 전 내가 Compose에 대한 이해가 상당히 미진하다는 점을 알린다.
Material3 라이브러리 버전
먼저 나는 이번 프로젝트에서 compose material3 라이브러리 최신 버전인 1.3.1을 사용했다.
pullToRefresh가 1.3.0 버전에서 추가되었기 때문이다.
제목에 굳이 웹뷰를 적은 이유
보통 android compose pulltorefresh를 검색어로 입력하면
LazyColumn에 있는 리스트를 갱신하는 예제가 매우 많다.
하지만, 나는 전체화면인 웹뷰 하나만 갱신하면 된다.
그마저도 웹페이지 로드 완료 여부에 따라 새로고침 UI 상태를 변경해주어야 한다.
페이지 다시 로드를 시작하고 완료되기까지 Indicator가 사라지면 안된다.
공식 문서 먼저 보기
일단 해당 문서에 pullToRefresh를 구현한 코드가 있다.
내가 구현한 코드
@ExperimentalMaterial3Api
@Composable
fun SampleWebView() {
var webView: WebView? by remember { mutableStateOf(null) }
var canGoBack by remember { mutableStateOf(false) }
var refreshState by remember { mutableStateOf(false) }
val state = rememberPullToRefreshState()
var isLoading by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val onRefresh: () -> Unit = {
coroutineScope.launch {
refreshState = true
isLoading = true
webView?.reload()
while (isLoading) {
delay(100)
}
refreshState = false
}
}
Scaffold { innerPadding ->
PullToRefreshBox(
modifier = Modifier.padding(innerPadding),
state = state,
isRefreshing = refreshState,
onRefresh = onRefresh,
) {
LazyColumn(modifier = Modifier.fillMaxSize()) {
item {
AndroidView(
modifier = Modifier
.fillParentMaxSize(),
factory = { context ->
WebView(context).apply {
with(settings) {
loadWithOverviewMode = true
useWideViewPort = true
javaScriptEnabled = true
javaScriptCanOpenWindowsAutomatically = true
domStorageEnabled = true
}
webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
canGoBack = view?.canGoBack() == true
}
}
webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(
view: WebView?,
newProgress: Int
) {
isLoading = newProgress != 100
}
}
loadUrl("https://www.naver.com")
}
},
update = {
webView = it
},
)
BackHandler(enabled = canGoBack) {
webView?.run {
if (canGoBack()) {
goBack()
}
}
}
}
}
}
}
}
사실 공식 문서와 거의 차이가 없다.
다만 onRefresh에서 실행되는 코루틴의 로직이 약간 다르다.
refresh 동작이 실행되면 isLoading, refreshState를 true로 변경하고
웹페이지 다시 로드를 시작, WebChromeClient 쪽에서 Progress가 100이 되면
isLoading이 false가 되면서 while문이 종료되고 refreshState도 false가 된다.
그리고 LazyColumn 내부를 보다시피 공식문서에서는 items로
리스트 아이템을 여러 개 생성하는 것을 볼 수 있었지만,
내 경우에는 item으로 AndroidView 하나만 가지고 있는 것을 볼 수 있다.
Composable 함수 이름이 SampleWebView임에도
Scaffold를 가지고 있는 것은 마음에 걸리지만
해당 부분은 Compose에 대한 숙련도 이슈로 넘어가면 좋겠다.
마치며
PullToRefresh API가 최근에 추가된 API이고,
다양한 예제가 있었지만 대부분 Flow, ViewModel과 같이 설명된 코드가 많아
이해하기 쉬운 코드가 필요했다.
내 코드가 아키텍처나 코틀린 이해도가 높지 않은 사람에게 좋지 않을까 생각한다.
어느 정도 Compose에서 UI를 구성하는 방법도 익히고 새로운 기능도 사용해보니 뿌듯했다.
'Android' 카테고리의 다른 글
Android Watchdog 기능 추가하기(OS 9) (0) | 2024.11.25 |
---|---|
Android Phone Number Format(자동 하이픈 추가) (0) | 2024.11.24 |
Android Fold Device 대응하기 (6) | 2024.11.08 |
Android Material Theme Elevation 해제하기 (4) | 2024.09.26 |
Android Material Library Update Story(feat. BottomNavigationView) (0) | 2024.07.14 |