가장 기본적으로 쓰는 scrollview.. 이 안에 리사이클러뷰를 넣으면 리사이클러뷰 스크롤이 안되고 전체 스크롤 뷰가 움직이는 현상이 있었다.
그래서 쓰게된,,
이걸 쓰고 나면 이제 스크롤도 되고 리사이클러뷰 스크롤도 잘 됐다! 그러나,,,!!!! 가끔 스크롤을 하다보면 코드대로 잘 작동을 안할 때가 있었다.
디버깅을 해보니 뷰가 다시 보이는데, bind()함수가 타지를 않는다..?!
이유 : NestedScrollView가 뷰 자체가 스크롤 됐다고 판단하고 recyclerview가 스크롤됐다고 생각하지 않는 것.
해결방법:
리사이클러뷰에 android:nestedScrollingEnabled="false"
속성 넣기
근데, 이 방법도 아주 큰 문제가 있었으니!!!
NestedScrollView 내부의 리사이클러뷰가 재활용 되지 않는다?!
NestedScrollView는 내부 리사이클러뷰의 아이템을 모두 그려놓는다. 따라서 재활용이 되지 않으며, 이는 리사이클러뷰의 장점을 크게 해치는 일이다!
바로바로.. 리사이클러뷰로 감싸버리기~!!(스크롤뷰 버리공)
여기서 위에 타일테스트라고 써있는 헤더타이틀 부분, 그리고 그 아래의 타일 리사이클러뷰 영역 총 2개의 영역으로 쪼갤 수 있다.
-> 이 기준으로 실제 xml을 분리해서 작성한다
1번에서전체 세로 리사이클러뷰
에 하나씩 넣기 위해 레이아웃들을 분리했다.
그럼 이제 핵심인 전체 세로 리사이클러뷰
를 만들어보자. (나는 이를 MainAdapter
, main.xml
이라 칭했다)
i) main.xml
을 만들어 세로 리사이클러뷰 하나를 가지도록 한다.
ii) MainAdaper
를 만든다.
iii) main.xml
레이아웃을 setContentView()
하는 액티비티나 프래그먼트에서 리사이클러뷰 세팅(어댑터는 MainAdaper
)을 한다.
MainAdaper
에서 신경써야하는 부분,,
private val list = listOf<Unit>(Unit, Unit)
헤더타이틀
과 타일영역
이 원래는 한 레이아웃에 있었기 때문에, binding.~~
의 형태로 서로의 뷰를 바로 접근 할 수 있었으나, 이제는 MainAdapter의 어떤 변수나 함수를 사용하여 접근하는 형태여야 한다.작성한 코드는 아래와 같습니당
class MainAdapter : RecyclerView.Adapter<MainCommonViewHolder>() {
private val list = listOf<Unit>(Unit, Unit)
val tileAdapter by lazy { TileAdapter() }
var startEditModeEventInAdapter: (() -> Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainCommonViewHolder {
val inflater = LayoutInflater.from(parent.context)
return if (viewType == TYPE_TITLE)
TitleViewHolder(ActivityMainTitleBinding.inflate(inflater, parent, false))
else
TileViewHolder(ActivityMainRvTileBinding.inflate(inflater, parent, false))
}
override fun onBindViewHolder(holder: MainCommonViewHolder, position: Int) {
holder.bind()
}
override fun getItemCount(): Int = list.size
override fun getItemViewType(position: Int): Int {
return if (position == 0) TYPE_TITLE
else TYPE_TILE
}
}
그럼 이 예제에서는 실제로 3개의 xml이 만들어지는 것.
+) 추가사항
2021년 10월쯤, ConcatAdapter
가 등장!!!
얘는 어댑터가 다양하게 존재할때 사용하면 너무 좋을 것 같다. 위에 만들어둔 리사이클러뷰로 감싸는 처리랑 비슷한 느낌이다.
예를 들어, 내가 원하는 뷰가 아래와 같은 형태를 띤다고 하자.
[A: 헤더 레이아웃 영역, B: 카드 리사이클러뷰 영역, C: 사진 리사이클러뷰 영역, D: 일기 리사이클러뷰 영역]
RecyclerView
로 처리ConcatAdapter
로 처리ConcatAdapter(여기에 4개의 어댑터 나열)
이런식으로 구현한다.