Compose로 검색 화면을 만들어보자

akcineg·2024년 6월 3일
0

안드로이드 공부

목록 보기
4/7
post-thumbnail

최근에 여러 앱을 사용했을 때 검색 화면들이 비슷한 포멧을 갖추는 것처럼 느꼈다.
상단에 있는 검색창을 터치하였을 때 최근 입력한 키워드, 추천 검색어와 같은 컴포넌트들이 배치된 화면이 표시된다. 검색창에 텍스트를 입력하였을 때 매치되는 검색 키워드들이 하단에 리스트로 나타난다.
이러한 흐름의 검색화면을 Jetpack Compose로 만들어보고자 한다.

목표

만들고자 하는 것은 검색창이 있는 메인 화면과 검색창을 터치하였을 때 진입할 검색 화면 크게 두 가지이다.

메인 화면에는 상단 좌측에는 메뉴 버튼 (작동 X), 우측에는 검색 버튼을 배치시킬 것이다.
검색 화면은 처음 진입했을 때 사용자가 최근에 입력한 검색 키워드들과 상위 10개의 인기 검색어를 볼 수 있도록 배치시킬 것이다. 키보드를 통해 검색어를 입력하는 경우에는 매치되는 키워드들을 표시하고 검색을 완료했을 때에는 간단하게 검색 결과를 텍스트로 표시하게 할 것이다.

초기 세팅

Jetpack Navigation, ViewModel, StateFlow 사용

화면 전환을 위해서 compose용 navigation 라이브러리를 사용하고, ViewModel에서 StateFlow 변수들을 사용해서 Composable 함수에서 사용하기 위해서 다음과 같이 종속 항목들을 추가하였다

navController와 navHost를 이용해 navigation을 구축하였다. 각 스크린의 이름에 맞게 route 이름을 정하였다. navController를 바탕으로 검색 버튼을 눌렀을 때 검색 화면으로 이동하게 하고, 검색 화면에서 이전 버튼(화살표)을 클릭하였을 때 메인 화면으로 돌아갈 수 있도록 하였다.

화면 만들기

메인 화면 생성

Scaffold와 TopAppBar를 이용해 간단하게 메인 화면을 만들어보았다. 우측 상단의 검색 버튼을 클릭 시 검색 화면으로 이동하게 할 예정이다.


검색 화면 생성

상단 검색 창 (SearchBox) 만들기

좌측에는 이전 (화살표) 버튼과 우측에는 검색 버튼, 가운데에는 검색 창(SearchFeield)를 배치시켰다.

상단 검색 창에서 구현하고 싶었던 것들
처음에는 검색 창은 Material3에서 지원하는 SearchBar를 바탕으로 쉽게 구성하려고 하였다. 그렇지만 막상 구성하려고 보니 내가 원하는 대로 UI를 커스텀하기가 힘들었다. 그래서 BasicTextField와 TextFieldDefaults.DecorationBox를 이용해서 원하는 대로 UI를 구성하였다.

검색 창을 만들고 테스트를 하였는데 검색 화면으로 진입하였을 때 바로 검색 창으로 focus가 되면서 키보드가 나타나지 않아 조금 불편하였다. 그래서 focusRequester객체와 requestFocus 함수를 이용하여서 검색 화면에 진입하였을 때(컴포지션이 발생했을 때) 바로 검색 창에 focus가 되어 바로 검색어를 입력할 수 있도록 하였다.

최근 검색어 컴포넌트 만들기

많은 앱들이 사용자가 입력한 최근 검색어를 검색 진입 화면에 배치하였기 때문에 나도 만들어보고 싶었다. 그래서 검색창에 검색어를 입력하였을 때 검색한 키워드들을 저장하고 UI에 표시할 수 있도록 하였다. 키워드 각각을 지울 수 있고 모두 지우기 버튼을 이용하여 모두 지울 수 있도록 구현하였다. 다만 메모리 상에서만 유지될 수 있도록 때문에 화면을 벗어나면 입력한 키워드들이 사라지도록 구현이 되어 있다. 이는 다음 포스트에서 개선할 예정이다.
구현을 위해서 Material3에서 지원하는 InputChip을 사용해 보았다. LazyRow를 바탕으로 수평으로 InputChip들을 배치하였다.

검색어 자동 완성 기능

검색어 자동 완성 기능은 거의 모든 앱에서 지원되는 기능이다. 사용자가 검색어를 입력하고 있는 도중에 매치되는 키워드들을 하단에 리스트로 표시하고 클릭하여 자동 완성 검색어에 대한 결과 화면으로 이동할 수 있도록 한다. 여러 앱에서 컴포즈로 어떻게 구현하는지 궁금하기도 해서 가볍게 구현해 보았다. 최근 검색어와 마찬가지로 서버나 로컬 DB에서 가져오는 키워드들이 아니라 테스트를 위해서 임의의 키워드들을 리스트로 만들어 사용해보았다. 현재 사용자가 입력한 키워드가 검색어 리스트에 있는 키워드를 일부 포함하고 있으면 하단에 리스트로 표시하도록 구현하였다.

경험해본 것
매칭이 되는 부분은 파란색으로, 아직 매칭이 되지 않은 부분은 검은색으로 키워드를 표시하고 싶었다. 직접 사용해본 경험은 없지만 XML 기반으로 UI를 구성할 때는 SpannableString을 이용하여 구현할 수 있는 것으로 알고 있었지만, Compose UI 방식에서는 어떻게 구현하는지 몰랐다. 그래서 어떻게 구현하는지 찾아보았는데 compose는 style이 적용된 String인 AnnotatedString이라는게 존재하였고, 이를 이용하여 내가 구현하고 싶은 것을 구현할 수 있었다.

앱 구동

느낀점

검색 화면을 만들어보기 위해서 여러 앱들을 사용해보면서 어떤 디테일들이 있는지를 테스트해보았다. 검색을 마친 상태에서 검색 창에 있는 X 버튼을 클릭할 때 단순히 입력한 키워드만 지운다면 사용자는 검색 창에 focus가 가지 않기 때문에 검색어를 바로 입력할 수 없다는 불편함이 존재한다. 이러한 불편함을 없애기 위해서는 많이 테스트해봐야 할 것 같다고 느꼈다. 사용자의 편의를 위해서 어떻게 동작해야 하는지를 곰곰이 생각을 잘 하면서 구현을 하는 개발자로 더욱 성장해야겠다.

만든 앱을 개선해서 Firebase를 이용하여 유저가 입력한 키워드들을 직접 서버가 관리할 수 있도록 해보겠다


궁금한 점이나 피드백 해주실 부분이 있다면 언제나 환영합니다!! 
profile
내 가치를 증명하자

0개의 댓글