스팀 앱 개발기 #68 - 태그 화면(TagsFragment) 구성
시작하며...
TagsViewModel 클래스를 구현하였구요. 이제는 태그별 포스트 리스트를 보여줄 TagFragment 클래스를 구현할 차례입니다. Kotlin 코딩을 하기 전에 우선적으로 해야 할 일은 바로 레이아웃을 구성하는 것입니다. 오늘은 바로 이 레이아웃을 만드는 작업을 할 예정입니다.
스크린샷
아래 그림과 같은 포맷으로 태그별 포스트 리스트 화면을 구현할 예정입니다.
화면 구조
태그별 포스트 리스트 화면은 다음과 같이 구성됩니다.
- Sort 선택
- trending, created, payout 중 하나의 정렬 방식 선택 가능
- 3개의 RadioButton으로 구성된 RadioGroup
- RadioButton: 선택시 검은 배경/하얀 텍스트, 비선택시 하얀 배경/검은 텍스트
- 포스트 리스트
- 화면에 보여줄 포스트 리스트
- 사용할 뷰: RecyclerView
- 포스트 리스트를 구성할 레이아웃: layout_post_item.xml 파일
작업 개요
- RadioButton의 배경색을 적용할 selector 정의
- RadioButton의 텍스트 색을 적용할 selector 정의
- RadioButton에 공통적으로 적용할 스타일 정의
- fragment_tags 레이아웃 구현
RadioButton의 배경색을 적용할 selector 정의
Sort 방식을 선택하기 위한 RadioButton의 배경색은 다음과 같이 정의해야 합니다. 이를 위한 selector를 아래와 같이 구현하였습니다.
| 조건 | 배경색 |
|---|---|
| 라디오 버튼 체크 | 검은색 |
| 라디오 버튼 미체크 | 하얀색 |
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<shape android:shape="rectangle">
<solid android:color="@color/black" />
<stroke android:width="1dp" android:color="@color/black" />
</shape>
</item>
<item android:state_checked="false">
<shape android:shape="rectangle">
<solid android:color="@color/white" />
<stroke android:width="1dp" android:color="@color/black" />
</shape>
</item>
</selector>
RadioButton의 텍스트 색을 적용할 selector 정의
Sort 방식을 선택하기 위한 RadioButton의 텍스트 색은 다음과 같이 정의해야 합니다. 이를 위한 selector를 아래와 같이 구현하였습니다.
| 조건 | 텍스트 색 |
|---|---|
| 라디오 버튼 체크 | 하얀색 |
| 라디오 버튼 미체크 | 검은색 |
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:color="@color/white">
</item>
<item
android:state_checked="false"
android:color="@color/black">
</item>
</selector>
RadioButton에 공통적으로 적용할 스타일 정의
라디오 버튼은 3개인데요. 이들의 외형은 동일하므로 이들의 속성을 일일이 설정하는 것은 비효율적입니다. 그것보다는 공통으로 적용할 속성들을 정의한 스타일을 정의하여 이 버튼들에 적용하는 것이 더 좋습니다. 이를 위한 스타일을 아래와 같이 themes.xml 파일에 정의하였습니다.
참고로 위에서 정의한 selector들을 이 스타일의 android:background, android:textColor로 설정하였습니다.
<style name="sort_radio_button">
<item name="android:background">@drawable/selector_sort_radio_btn_bg</item>
<item name="android:button">@null</item>
<item name="android:padding">5dp</item>
<item name="android:textAlignment">center</item>
<item name="android:textColor">@drawable/selector_sort_radio_btn_text</item>
<item name="android:textSize">15dp</item>
<item name="android:textStyle">bold</item>
</style>
- android:button - 좌측의 원 모양을 없애기 위해 @null로 설정
- android:textAlignment - 텍스트가 한가운데로 보이기 위해 center로 설정
fragment_tags 레이아웃 구현
위에 보여드린 화면 구조대로 레이아웃을 구성하였습니다. 상단의 Sort 선택은 RadioGroup 뷰가 최상위구요. 그 아래에 포스트 리스트를 보여줄 RecyclerView 뷰를 배치했습니다.
맨 아래 위치한 TextView 뷰는요. 화면 구현 작업하면서 제거할 예정입니다.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioGroup
android:id="@+id/radiogroup_sort"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent">
<RadioButton
android:id="@+id/radiobtn_trending"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="true"
android:text="trending"
style="@style/sort_radio_button" />
<RadioButton
android:id="@+id/radiobtn_created"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="false"
android:text="created"
style="@style/sort_radio_button" />
<RadioButton
android:id="@+id/radiobtn_payout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="false"
android:text="payout"
style="@style/sort_radio_button" />
</RadioGroup>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_post_item"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/radiogroup_sort"
app:layout_constraintBottom_toBottomOf="parent"
tools:listitem="@layout/layout_post_item" />
<TextView
android:visibility="gone"
android:id="@+id/text_tags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="@{viewModel.text}"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
GitHub Commit
마치며...
이번 포스트는 생각보다 어렵지 않게 작성할 수 있었습니다. 이전에 작업을 하면서 노하우가 쌓인 것이 아닌가 합니다. 앞으로도 작업이 좀 더 순조로워지기를 기대해 봅니다.
지난 스팀 앱 개발기
- #66 - bridge.get_ranked_posts API 연동 구현: ReadRankedPostsUseCase 클래스 추가
- #65 - bridge.get_ranked_posts API 연동 구현: SteemRepository 인터페이스, SteemRepositoryImpl 클래스 수정
- #64 - bridge.get_ranked_posts API 연동 구현: SteemService 인터페이스에 메소드 추가
- #63 - bridge.get_ranked_posts API 관련 데이터 클래스 추가 수정
- #62 - bridge.get_ranked_posts API의 응답 자료를 맡을 데이터 클래스 수정
- #61 - layout_post_item.xml 수정 후 예상치 못한 빌드 오류
- #60 - bridge.get_ranked_posts API의 응답 자료를 맡을 데이터 클래스 정의
- #59 - 태그별 포스트 리스트를 구하기 위한 bridge.get_ranked_posts API
- #58 - 포스트 리스트를 구성할 항목의 레이아웃 (3) 데이터 클래스 정의 및 데이터 바인딩 적용
- #57 - 포스트 리스트를 구성할 항목의 레이아웃 (2)
- #56 - 포스트 리스트를 구성할 항목의 레이아웃
- #55 - .gitignore 파일 작성
- #54 - RxJava 관련 메모리 누수 방지 코드 작성
- #53 - 버그 수정: 인터넷 미연결시 API 실행하면 앱 강제 종료
- #52 - 인터넷 미연결시 API 실행하면 어떻게 될까?
- #51 - 파워다운 끝났으나 SP to power down 값이 0이 아닌 버그
- #1 ~ #50
Posted through the AVLE Dapp (https://avle.io)

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.
Upvoted! Thank you for supporting witness @jswit.
와우 멋집니다.