ChipGroup으로 필터검색을 사용해보자!

GongBaek·2024년 5월 30일
post-thumbnail



그림까지 그려주는 우리 친절한 서버쌤...

이번 합동세미나에서 위와 같은 API가 있었는데, 바텀시트로 올라와서 선택한 만큼만 List 형태로 전송해줘야 하더라구요?!

약간 아찔해져서 어떻게 해야 할까 고민중이었는데 생각보다 어렵지 않았습니다!!

Chip이라는 컴포넌트를 아시나요?

저는 Chip과 ChipGroup이 있다는 것만 알고 자세한 사용법은 알지 못했었는데,

그래서 각 카테고리 버튼마다 id를 하나씩 부여해줬습니다.

<com.google.android.material.chip.ChipGroup
        android:id="@+id/cgSearchCategory"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="22dp"
        app:chipSpacingHorizontal="12dp"
        app:chipSpacingVertical="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tvSearchCategoryTitle">

        <com.google.android.material.chip.Chip
            android:id="@+id/chipSearchCategory1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checkable="true"
            android:minHeight="34dp"
            android:text="@string/searchCategory1"
            android:textAppearance="@style/body"
            android:textColor="@drawable/selector_search_category_font"
            app:chipBackgroundColor="@drawable/selector_search_category_background"
            app:chipCornerRadius="3dp"
            app:chipStrokeColor="@drawable/selector_search_category_stroke"
            app:rippleColor="@null" />
    </com.google.android.material.chip.ChipGroup>

하지만 id를 넣어줄 필요가 없더라구요? 이유를 알아볼까요~~ㅎㅎ

정답은 바로 ChipGroup의 기본 확장함수에 있답니다 🤭

    private fun setCheckedCategories() {
        val checkedCategories = mutableListOf<Int>()
        binding.cgSearchCategory.forEachIndexed { index, view ->
            if (view is Chip && view.isChecked) checkedCategories.add(index + SERVER_CATEGORY_OFFSET)
        }
        viewModel.setCheckedCategories(checkedCategories)
    }

제가 작성한 함수가 보이시나요?!

카테고리를 저장하는 mutableList를 만들고 ChipGroup의 .forEachIndexed 라는 친구를 사용했답니다!! 칩그룹에 들어있는 순서대로 뷰를 받아오고, 그 순서에 따라 index도 지정해줘서 칩그룹 내의 모든 칩을 사용할 수 있게 됩니다.

이렇게 각 체크된 칩들의 정보를 뷰모델로 넘겨주고 서버통신을 한 결과, 성공적으로 코드가 돌아가는 것을 볼 수 있었습니다.

    @GET("positions")
    suspend fun getPositions(
        @Query("keyword") keyword: String,
        @Query("categories") categories: List<Int>,
    ): BaseResponse<SearchResultsResponse>
2024-05-23 13:50:09.639  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> <-- END HTTP (2399-byte body)
2024-05-23 13:50:12.842  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> --> GET http://13.124.231.172/api/v1/positions?keyword=%ED%86%A0%EC%8A%A4&categories=10&categories=12
2024-05-23 13:50:12.842  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> --> END GET
2024-05-23 13:50:12.892  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> <-- 200 http://13.124.231.172/api/v1/positions?keyword=%ED%86%A0%EC%8A%A4&categories=10&categories=12 (50ms)
2024-05-23 13:50:12.893  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> Server: nginx/1.18.0 (Ubuntu)
2024-05-23 13:50:12.893  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> Date: Thu, 23 May 2024 04:50:13 GMT
2024-05-23 13:50:12.893  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> Content-Type: application/json
2024-05-23 13:50:12.893  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> Transfer-Encoding: chunked
2024-05-23 13:50:12.893  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> Connection: keep-alive
2024-05-23 13:50:13.229  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> 
2024-05-23 13:50:13.230  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> {"status":200,"message":"[SUCCESS] 채용 공고 검색이 완료되었습니다.","data":{"position":[{"company":{"id":1,"name":"토스뱅크","image":"https://drive.google.com/file/d/1TliH1yADLU_2pmpy6PjavnkqWjdJ9MGa/view?usp=drive_link","description":"토스뱅크"},"id":1,"title":"[토스뱅크] Frontend Developer","skills":[{"name":"Java","image":"https://drive.google.com/file/d/1fzcywm3TU3pxplvZmANB8menETXjzhju/view?usp=sharing"},{"name":"JavaScript","image":"https://drive.google.com/file/d/1zQZEa0fRuEVBxbNLekBaJFDltt0Jf-Zy/view?usp=sharing"}]},{"company":{"id":1,"name":"토스뱅크","image":"https://drive.google.com/file/d/1TliH1yADLU_2pmpy6PjavnkqWjdJ9MGa/view?usp=drive_link","description":"토스뱅크"},"id":2,"title":"[토스뱅크] System Engineer","skills":[{"name":"Python","image":"https://drive.google.com/file/d/1wqc1wCoNWmLRiaowB0XRJ4Khq2gQrUN7/view?usp=sharing"},{"name":"React.js","image":"https://drive.google.com/file/d/1qx52IsBESJKDd1ebd9EfK6OHn0jwro5M/view?usp=sharing"}]},{"company":{"id":1,"name":"토스뱅크","image":"https://drive.google.com/file/d/1TliH1yADLU_2pmpy6PjavnkqWjdJ9MGa/view?usp=drive_link","description":"토스뱅크"},"id":3,"title":"[토스뱅크] QA Manager","skills":[{"name":"Spring Framework","image":"https://drive.google.com/file/d/1xfnzrfDHMRSPilU9NT1gKWSMkKLHX-mG/view?usp=sharing"},{"name":"Angular","image":"https://drive.google.com/file/d/1IwLpGpaaedM572wP8UtE_XU0fd0PpT6Y/view?usp=sharing"}]},{"company":{"id":1,"name":"토스뱅크","image":"https://drive.google.com/file/d/1TliH1yADLU_2pmpy6PjavnkqWjdJ9MGa/view?usp=drive_link","description":"토스뱅크"},"id":4,"title":"[토스뱅크] Full Stack Developer (Admin)","skills":[{"name":"Node.js","image":"https://drive.google.com/file/d/1ghI6mwvnh5PVDM5eaIYsjMa0K5eUtInR/view?usp=sharing"},{"name":"SQL","image":"https://drive.google.com/file/d/1HVTB0lTdaMtbV0UurvNtGNAmrzVNnos9/view?usp=sharing"}]},{"company":{"id":2,"name":"비바리퍼블리카","image":"https://drive.google.com/file/d/1NpLYKmnIEqLyPUSXF4I_hs9N-QRd9A36/view?usp=drive_link","description":"비바리퍼블리카"},"id":5,"title":"[토스] Financial System Engineer","skills":[{"name":"MongoDB","image":"https://drive.google.com/file/d/1YZxfePnQx-Wynqa6UfuINXZAaTQ80IuM/view?usp=sharing"},{"name":"HTML/CSS","image":"https://drive.google.com/file/d/1ATh44pn8cCR3jD4BoKgNPW-vVmEeIx6m/view?usp=sharing"}]}]}}
2024-05-23 13:50:13.231  4635-4701  Retrofit2               com.sopt.now.jumpit                  D  CONNECTION INFO -> <-- END HTTP (2399-byte body)

categories가 필수가 아니라 일반 검색과 상세검색을 따로 구별하지 않아도 되더라구요!

이상 필터검색에 대한 트러블슈팅이었답니다 😎

List 라는 친구는 생각보다 많은 확장함수를 보유중인가봐요!! 이에 대해 좀 더 공부해봐도 좋을 것 같았습니다.

그리고 theme 에서 스타일좀 잘 만져보면 더 코드 줄일 수 있을거같은데 못줄여서 아쉽네용…! 역시 커스텀뷰는 시간이 오래걸리는 작업 🥺 웹소소는 커스텀칩이 적용되어 있지만요~~😏

아래는 시연영상입니다!!

profile
Junior Android Developer

0개의 댓글