1. 고민 고민
- NestedScrollView가 싫다.
- 그래서, Coordinator Layout을 통해서 다양한 뷰와 리사이클러 뷰의 성능상 이점을 갖는 구조를 만들었다.
- 새로 고침 기능이 필요해졌다.
- SwipeRefreshLayout이 필요하다.
- SwipeRefreshLayout은 CoordinatorLayout에서는 어떻게 사용할까?
- RecyclerView의 behavior는 어떻게 해야할까?
지난 글과 같이, NestedScrollView를 사용하지 않고, 리사이클러뷰에 다양한 뷰홀더를 만들어서 뷰 구조를 잡았다.
그 과정에서, CoordinatorLayout을 이용해서 리사이클러뷰의 재활용과 백드롭 등, 다양한 이점을 가져오고 있었다. 그리고, 새로 고침 기능이 필요해졌다. 그러면 어떻게 뷰 구조를 잡아야할까?
2. 생각보다 간단한 뷰구조
뷰 구조가 정말 심플하다. 기존에는 RecyclerView에 behavior가 설정되어 있었는데, SwipeRefreshLayout에 behavior를 이동시켜주면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="subtitle" type="String"/> </data> <androidx.coordinatorlayout.widget.CoordinatorLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/view_content_background"> <!-- 툴바 관련 --> <include layout="@layout/layout_coordinator_toolbar"/> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/srl_contents" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_contents" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="@dimen/content_card_side_dimen" android:paddingEnd="@dimen/content_card_side_dimen" android:paddingBottom="@dimen/bottom_sheet_min_height"/> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <include android:id="@+id/bottom_sheet_container" layout="@layout/layout_bottom_sheet"/> </androidx.coordinatorlayout.widget.CoordinatorLayout> </layout> | cs |
3. 로직
로직에서 많이 애를 먹었다. 계속해서 애니메이션이 먼저 발생했기 때문이다. 그래서, 구글링을 이것 저것 돌려본 결과, isRefreshing이 순탄한 로직으로 되고 있지 않아서 였다. 아래와 같이 로직을 잡으면, 무조건 될 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | //MyActivity, MyFragment, etc... //make presnter private val presenter by lazy { ContentViewPresenter(this) } //make viewBinding private val viewContentBinding = provideDataBinding() //initView override fun initView() { viewContentBinding.let { it.srlContents.post { it.srlContents.setOnRefreshListener(refreshListener) } } } //refreshView override fun refreshView() { presenter.initView() viewContentBinding.srlContents.post { if(viewContentBinding.srlContents.isRefreshing){ viewContentBinding.srlContents.isRefreshing = false } } } //make SwipeRefreshListener private val refreshListener = SwipeRefreshLayout.OnRefreshListener { viewContentBinding.srlContents.post { if(!viewContentBinding.srlContents.isRefreshing){ viewContentBinding.srlContents.isRefreshing = true } presenter.getChatContents("0001") } } //1. initView //2. call swipeRefreshListener //3. ended presenter logic. //4. refreshView | cs |
1. 우선, 자신의 라이프사이클에 맞게 view를 초기화 해준다.
2. 초기화 할 때, refreshListener를 달아준다. 해당 리스너는 isRefreshing 상태가 false라면, true로 스와이프 애니메이션이 나타나게 해준다.
3. presneter.getChatContents()와 같이 자신만의 비지니스 로직을 호출한다.
3-1. 내가 구현한 getChatContents는 Database에 접근하고, onFinished가 됐을 때, 자동적으로 refreshView()를 호출한다.
4. 해당 로직이 호출이 종료되면, refreshView()가 호출이 된다.
5. 그 때, 획득한 데이터를 통해서, 다시 뷰를 초기화 해주고, isRefreshing이 true이면, 애니메이션이 사라지도록 false로 바꿔준다.
4. Result
'Android 공부 > Android UI' 카테고리의 다른 글
Android DarkTheme 도입기 (0) | 2020.04.30 |
---|---|
안드로이드 - Jetpack Navigation 사용 [코드 리팩토링] (0) | 2020.04.04 |
NestedScrollView 없이 RecyclerView를 사용해보자. (1) | 2019.09.13 |
[안드로이드 UI 공부] Android Shared-Element Transitions - 2 (0) | 2019.04.12 |
[안드로이드 UI 공부] Android Shared-Element Transitions - 1 (0) | 2019.04.10 |