RecyclerView No adapter attached; skipping layout | 삽질 노트

hoya·2022년 3월 19일
2

삽질 노트

목록 보기
6/8
post-thumbnail

😡 문제 상황

private val adapter : UserAdapter by lazy {
    UserAdapter()
}

override fun initStartView() {
    binding.recyclerView.apply {
        this.layoutManager = LinearLayoutManager(this@UserActivity)
        this.adapter = adapter // Error !
        this.addItemDecoration(RecyclerViewDecoration(10))
        this.setHasFixedSize(true)
    }
}

override fun initDataBinding() {
    viewModel.userFavoriteList.observe(this) {
        adapter.submitList(it)
    }
}

두 눈 크게 뜨고 아무리 봐도 내 코드는 멀쩡한데 리사이클러뷰에 어댑터가 적용되지 않았다는 오류가 발생했다.


🤔 원인 파악

이런 경우 사실 여러 매뉴얼이 있다.

  1. setAdapter 했니?
    -> this.adapter = adapter
  2. 리사이클러뷰 어댑터의 getItemCount() 메소드에서 카운트를 0으로 설정한거 아니야?
    -> override fun getItemCount(): Int = favoriteList.size
  3. 레이아웃 매니저는 설정했어?
    -> this.layoutManager = LinearLayoutManager(this@UserActivity)
  4. 혹시 프래그먼트에서 어댑터 설정하는거면, onCreate() 부분이 아니라 onCreateView() 에서 해줘야돼.
  5. binding 쓰는거면, setContentView(R.layout.activity_main) 이 아니라, setContentView(binding.root) 로 설정해야돼.

일단 기본적인 매뉴얼은 이렇지만, 저 조건을 모두 충족했음에도 결과가 나타나지 않았다.
이리저리 해매면서 머리를 싸매고 있던 도중...

코드를 살짝 지웠는데, 전역변수로 설정한 adapter 가 사용되지 않고 있다는 알림이 나타났다.

😭 apply를 쓰는 과정에서 this의 대상이 내가 기대한 UserActivity가 아니라 리사이클러뷰가 된 것이다.


😎 해결

private val adapter : UserAdapter by lazy {
    UserAdapter() // outer scope
}

override fun initStartView() {

    binding.recyclerView.apply {
        this.layoutManager = LinearLayoutManager(this@UserActivity)
        this.adapter = this@UserActivity.adapter // Qualified this
        this.addItemDecoration(RecyclerViewDecoration(10))
        this.setHasFixedSize(true)
    }
}

override fun initDataBinding() {
    viewModel.userFavoriteList.observe(this) {
        adapter.submitList(it)
    }
}

코틀린에서 안내하는 자격(Qualified) this를 이용하여 외부 범위에 있는 액티비티의 전역 변수를 끌어올 수 있다.


참고 및 출처

코틀린 공식 문서

profile
즐겁게 하자 🤭

0개의 댓글