시리즈

[Android] RecyclerView 1

20190804
android
recyclerview

RecyclerView 기초


개념

준비물

RecyclerView에 데이터를 보여주기 위해서 다음 부품들이 필요하다.
이름 설명
데이터들
RecyclerView 인스턴스 xml 레이아웃 안에 선언하면 된다.
LayoutManager 아이템을 조직화해준다. 어떻게 배치할지를 결정한다. app:layoutManager 속성을 이용한다.
하나의 데이터를 표현할 레이아웃 아이템 레이아웃
ViewHolder 아이템 레이아웃에서 정보를 가져와서 코드와 연결시킨다. 뷰를 레퍼런스와 연결한다.
Adapter 데이터를 준비하고 ViewHolder에서 어떻게 보여질 지를 정한다.

구현

LayoutManager 있는 RecyclerView 추가






Show Details
  1. RecyclerView를 xml 레이아웃에 추가한다.
    1. 여기서 대화상자가 나오면서 gradle 의존성 추가할 건지를 물어보면 OK를 눌러주자.
    2. build.gradle(module:app) 에서 다음 코드가 있는지 확인하자.(버전은 다를 수 있다.)
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
  2. 다시 xml 레이아웃으로 돌아와 Text 탭으로 들어가자.
  3. recyclerview의 xml을 필요한 만큼 수정하자. (id, constraint 속성 등등)
  4. layoutManager 속성을 추가한다. (여기서는 LinearLayoutManager)

ViewHolder 만들기






Show Details
레이아웃 작성
xml 파일에 레이아웃 작성
뷰 홀더 만들기
RV.VH(View) 를 확장해서 클래스 선언. 파일을 따로 만들어도 되지만 자바 스타일은 1파일 1클래스가 원칙이기 때문에 어댑터 클래스 안에 내부 클래스로 만드는 경우가 많음. 코틀린에서는 그냥 따로 만드는 것도 방법.

어댑터 작성






Show Details

어댑터 작성

  1. RecyclerView.adapter 를 확장한 어댑터 클래스를 만든다.
RecyclerView는 데이터가 어떻게 변하고 있는지를 모르기 때문에 notifyDataSetChanged() 를 이용해서 데이터에 맞게 모든 리스트를 다시 그리게 해야 한다.
  1. 에러 표시가 뜨면 alt+enter 를 눌러서 onCreateViewHolder(), getItemCount(), onBindViewHolder() 를 오버라이드 한다.
  2. getItemCount() 를 작성한다. 보통 data.size가 된다.
  1. onBindViewHolder() 를 구현한다. 특정한 위치에 하나의 데이터를 위한 뷰를 만들어 주는 함수다. 두 개의 인수를 가진다.
    • 하나의 view holder
    • bind할 데이터의 position
아래는 간단한 예시
  1. onCreateViewHolder() 를 구현한다. RecyclerView가 하나의 아이템을 표현할 뷰 홀더가 필요할 때마다 호출된다. 이 함수는 2개의 매개변수를 가지고 하나의 뷰 홀더를 리턴한다.
    • parent 매개변수 (항상 RecyclerView가 된다.)
    • viewType 매개변수는 같은 RecyclerView에 여러 개의 뷰가 존재할 때 사용된다. (텍스트뷰들, 이미지, 비디오 등등을 같은 RecyclerView에 넣어버린 경우에 어떤 것을 위한 뷰 홀더를 만들지를 결정한다.)
예시

어댑터 달기
RV가 들어있는 코드로 가서 만들어준 어댑터를 달아준다.
사용할 데이터 넣어주기.

코드 리팩토링

뷰 홀더에만 관련된 코드들이 어댑터에 있는 상태이다. 이런 코드들을 ViewHolder 안으로 옮겨서 구조적으로 개선. 뷰 홀더를 보여주는 코드와 관리하는 코드를 결합시키고 onBindViewHolder() 에서 ViewHolder를 어떻게 업데이트하는지 세부 사항을 알게 한다.
앱을 만들 때는 여러 개의 뷰 홀더와 복잡한 어댑터들, 변경점을 만드는 개발자들이 있게 된다. 이런 상황을 대비해서 뷰 홀더에 관련된 모든 것들은 반드시 그 뷰 홀더에만 있도록 만들어야 한다.

onBindViewHolder() 리팩토링

목적 : 보여지는 것은 바뀌지 않지만 더 쉽고 안전한 작업을 하도록 도와준다.
  1. onBindViewHolder에서 item 선언을 제외한 모든 코드를 선택해서, Refactor > Extract > Function 을 이용해서 함수로 만든다. 함수 이름은 bind() 로 하자.
  2. 이제 함수 시그니쳐의 홀더 위에 커서를 놓고 Alt(Option) + Enter 를 눌러서 Convert parameter to receiver 를 선택한다.
  1. bind() 함수를 ViewHolder 안으로 옮긴다.
  2. bind() 를 public 으로 바꾼다.
  3. bind() 를 ViewHolder 안으로 옮겼기 때문에 ViewHolder를 앞에 적어줄 필요는 없다.

onCreateViewHolder() 리팩토링

onCreateViewHolder() 메소드는 어댑터에 있고, 이 코드는 뷰 홀더를 레이아웃 리소스에서 인플레이트해주는 역할을 한다. 하지만 이건 어댑터와는 전혀 상관없고 모두 ViewHolder를 통해서 이루어진다. 그러니 뷰 홀더로 코드를 옮겨줘야 한다.
  1. onCreateViewHolder의 모든 코드를 선택한다.
  2. Refactor > Extract > Function. 함수 이름은 from으로 하자.
  3. from 함수 위에 커서를 놓고 Alt(Option) + Enter 를 누른다.
  4. Move to companion object 를 선택하자. companion object 로 옮겨서 VH 인스턴스가 아니라 VH 클래스에서 호출되게 만들어야 한다.
  5. 만들어진 companion object 를 ViewHolder 클래스로 옮긴다.
  6. from() 함수를 public 으로 바꾼다.
  7. onCreateViewHolder() 메소드에서 return 부분을 ViewHolder.from(parent) 로 바꾼다.
  1. 이제 뷰 홀더 클래스 생성자를 private 으로 바꿔주자. 어차피 from() 을 통해서 새로운 인스턴스가 만들어진다.

.

piano (press key Q)

Categories

flutter ( 82 ) dart ( 34 ) android ( 32 ) kotlin ( 11 ) plugin ( 8 ) provider ( 8 ) vim ( 7 ) bloc ( 6 ) iOS ( 6 ) state management ( 6 ) 플러터 ( 6 ) PS ( 5 ) algorithm ( 5 ) architecture ( 5 ) async ( 5 ) getx ( 5 ) java ( 5 ) API ( 4 ) BOJ ( 4 ) class ( 4 ) daily ( 4 ) git ( 4 ) golang ( 4 ) memo ( 4 ) riverpod ( 4 ) state ( 4 ) stream ( 4 ) test ( 4 ) web ( 4 ) widget ( 4 ) windows ( 4 ) HTTP ( 3 ) androidX ( 3 ) app state ( 3 ) context ( 3 ) crash ( 3 ) db ( 3 ) editor ( 3 ) error ( 3 ) extension ( 3 ) github ( 3 ) hive ( 3 ) ide ( 3 ) package ( 3 ) pubspec ( 3 ) python ( 3 ) syntax ( 3 ) vscode ( 3 ) app icon ( 2 ) await ( 2 ) chocolatey ( 2 ) consumer ( 2 ) cp949 ( 2 ) deployment ( 2 ) dev ( 2 ) flavor ( 2 ) gesture ( 2 ) globalkey ( 2 ) go ( 2 ) google ( 2 ) hack ( 2 ) js ( 2 ) json ( 2 ) key ( 2 ) keystore ( 2 ) list ( 2 ) listview ( 2 ) lock ( 2 ) mac ( 2 ) map ( 2 ) navigation ( 2 ) nosql ( 2 ) project ( 2 ) pub ( 2 ) recyclerview ( 2 ) rxdart ( 2 ) sdk ( 2 ) selector ( 2 ) setting ( 2 ) size ( 2 ) soc ( 2 ) synchronized ( 2 ) tdd ( 2 ) tip ( 2 ) version ( 2 ) viewmodel ( 2 ) vundle ( 2 ) webview ( 2 ) xcode ( 2 ) yaml ( 2 ) ( 2 ) 플러터 단점 ( 2 ) 16.0 ( 1 ) 2.0 ( 1 ) 2023 ( 1 ) AATP2 ( 1 ) ChangeNotifierProvider ( 1 ) Example ( 1 ) Guava ( 1 ) ImageReader ( 1 ) Mo's algorithm ( 1 ) OAuth2 ( 1 ) OpenGL ( 1 ) Oreo ( 1 ) ProgressBar ( 1 ) REST API ( 1 ) Trie ( 1 ) activity ( 1 ) adaptive ( 1 ) android P ( 1 ) android context ( 1 ) android11 ( 1 ) apktool2 ( 1 ) app exit ( 1 ) append ( 1 ) appicon ( 1 ) arkit ( 1 ) array ( 1 ) asciidoc ( 1 ) async * ( 1 ) async* ( 1 ) audio ( 1 ) authorization ( 1 ) await for ( 1 ) behaviorsubject ( 1 ) beta ( 1 ) binary ( 1 ) binarysearch ( 1 ) blender ( 1 ) book ( 1 ) bottomsheet ( 1 ) break ( 1 ) broadcast ( 1 ) browser ( 1 ) bubbles ( 1 ) bug ( 1 ) build ( 1 ) buildcontext ( 1 ) buildnumber ( 1 ) bundle ( 1 ) button ( 1 ) bytecode ( 1 ) cache ( 1 ) camera2 ( 1 ) cameramanager ( 1 ) cd ( 1 ) chrome ( 1 ) ci ( 1 ) circle ( 1 ) clean ( 1 ) clean architecture ( 1 ) cli ( 1 ) clip ( 1 ) clipboard ( 1 ) cloud ide ( 1 ) cmdlet ( 1 ) code ( 1 ) coding test ( 1 ) command ( 1 ) comparator ( 1 ) complexity ( 1 ) concurrency ( 1 ) conditional ( 1 ) const ( 1 ) constraint ( 1 ) constraintlayout ( 1 ) controlc ( 1 ) controlv ( 1 ) converter ( 1 ) copy ( 1 ) copy project ( 1 ) coupling ( 1 ) coverage ( 1 ) cp ( 1 ) css ( 1 ) cupertino ( 1 ) cursor ( 1 ) cv ( 1 ) data class ( 1 ) data structure ( 1 ) dataBinding ( 1 ) database ( 1 ) debounce ( 1 ) decompile ( 1 ) delegate ( 1 ) deno ( 1 ) design pattern ( 1 ) development ( 1 ) device ( 1 ) di ( 1 ) dialog ( 1 ) dio ( 1 ) drawable ( 1 ) drug ( 1 ) emmet ( 1 ) encoding ( 1 ) english ( 1 ) entries ( 1 ) environment ( 1 ) equality ( 1 ) equatable ( 1 ) euc-kr ( 1 ) euckr ( 1 ) exit ( 1 ) expand ( 1 ) expanded ( 1 ) export ( 1 ) extension method ( 1 ) facade ( 1 ) fake ( 1 ) field ( 1 ) figma ( 1 ) final ( 1 ) fixed ( 1 ) flutter pub ( 1 ) flutter web ( 1 ) flutter_inappwebview ( 1 ) flutter_test ( 1 ) flutterflow ( 1 ) fold ( 1 ) fonts ( 1 ) form ( 1 ) frame ( 1 ) future ( 1 ) gestureDetector ( 1 ) gestureRecognizer ( 1 ) gesturearena ( 1 ) get-command ( 1 ) get_cli ( 1 ) getbuilder ( 1 ) getx단점 ( 1 ) gitignore ( 1 ) glut ( 1 ) google fonts ( 1 ) gopath ( 1 ) goto ( 1 ) gradient ( 1 ) graphics ( 1 ) gvim ( 1 ) hackaton ( 1 ) hash ( 1 ) hashmap ( 1 ) hot reload ( 1 ) how to ( 1 ) html ( 1 ) i18n ( 1 ) icon ( 1 ) id ( 1 ) impeller ( 1 ) implementation ( 1 ) import ( 1 ) indicator ( 1 ) inkwell ( 1 ) interrupt ( 1 ) intl ( 1 ) introduction ( 1 ) io ( 1 ) isar ( 1 ) iterable ( 1 ) iteration ( 1 ) javascript ( 1 ) julia ( 1 ) juno ( 1 ) jupyter ( 1 ) kakaomap ( 1 ) keytool ( 1 ) korean ( 1 ) kotlin syntax ( 1 ) l10n ( 1 ) lambda ( 1 ) language ( 1 ) layer ( 1 ) layout ( 1 ) lineageOS ( 1 ) localkey ( 1 ) localtoglobal ( 1 ) long list ( 1 ) ls ( 1 ) mac osx ( 1 ) markdown ( 1 ) markup ( 1 ) material ( 1 ) method ( 1 ) microtask ( 1 ) migrate ( 1 ) mintlify ( 1 ) mock ( 1 ) module ( 1 ) monitor ( 1 ) moor ( 1 ) mouse ( 1 ) mouseregion ( 1 ) multiplatform ( 1 ) multiset ( 1 ) multithread ( 1 ) mutable ( 1 ) mvvm ( 1 ) new ( 1 ) node ( 1 ) nodejs ( 1 ) nosuchmethod ( 1 ) null-safety ( 1 ) numberformat ( 1 ) nvim ( 1 ) object ( 1 ) objectbox ( 1 ) objectkey ( 1 ) obx ( 1 ) online ide ( 1 ) operator ( 1 ) orientation ( 1 ) parabeac ( 1 ) parse ( 1 ) paste ( 1 ) path ( 1 ) pattern ( 1 ) pitfall ( 1 ) play store ( 1 ) pod ( 1 ) podfile ( 1 ) pointer ( 1 ) pointers ( 1 ) powershell ( 1 ) private ( 1 ) programming ( 1 ) pull to refresh ( 1 ) puzzle ( 1 ) pycharm ( 1 ) realitykit ( 1 ) recursion ( 1 ) reduce ( 1 ) reference ( 1 ) regex ( 1 ) regular expression ( 1 ) release note ( 1 ) renderbox ( 1 ) renderobject ( 1 ) repl ( 1 ) repository ( 1 ) response ( 1 ) rm ( 1 ) rotue ( 1 ) round ( 1 ) run ( 1 ) scope ( 1 ) scroll ( 1 ) search ( 1 ) server ( 1 ) serverless ( 1 ) service ( 1 ) sharp ( 1 ) singlerepo ( 1 ) singleton ( 1 ) sketch ( 1 ) sliver ( 1 ) sliverlist ( 1 ) snippets ( 1 ) sogae ( 1 ) sorting ( 1 ) source ( 1 ) sparse ( 1 ) sparse array ( 1 ) spec ( 1 ) split ( 1 ) sqflite ( 1 ) sqlite ( 1 ) sqrt decomposition ( 1 ) stateful ( 1 ) statefulwidget ( 1 ) step ( 1 ) stepper ( 1 ) string ( 1 ) stringbuffer ( 1 ) stringbuilder ( 1 ) studio ( 1 ) study ( 1 ) sub-directory ( 1 ) svn ( 1 ) swiftui ( 1 ) swipe to refresh ( 1 ) system_alert_window ( 1 ) system_cache ( 1 ) systemnavigator ( 1 ) tail recursion ( 1 ) tailrec ( 1 ) tap test ( 1 ) text ( 1 ) texteditingcontroller ( 1 ) textfield ( 1 ) texttheme ( 1 ) themedata ( 1 ) then ( 1 ) thread ( 1 ) throttle ( 1 ) time ( 1 ) tool ( 1 ) tools ( 1 ) tooltip ( 1 ) ts ( 1 ) tutorial ( 1 ) typescript ( 1 ) ui ( 1 ) unittest ( 1 ) update ( 1 ) usb ( 1 ) utf8 ( 1 ) ux ( 1 ) valuekey ( 1 ) variable ( 1 ) vector ( 1 ) versioncode ( 1 ) very_good ( 1 ) view ( 1 ) vim plugin ( 1 ) vimrc ( 1 ) virtualenv ( 1 ) wasm ( 1 ) web app ( 1 ) webview_flutter ( 1 ) while ( 1 ) widget tree ( 1 ) window ( 1 ) wsl ( 1 ) yield ( 1 ) 강의 ( 1 ) 개발 ( 1 ) 개발 공부 ( 1 ) 공부법 ( 1 ) 그래픽스 ( 1 ) 꼬리재귀 ( 1 ) 꿀팁 ( 1 ) 데노 ( 1 ) 두줄 ( 1 ) 디노 ( 1 ) 번역 ( 1 ) 블록 ( 1 ) 상태관리 ( 1 ) 실험 ( 1 ) 안드로이드 ( 1 ) 안드로이드프로젝트 ( 1 ) 안드로이드프로젝트복사 ( 1 ) 어이없는 ( 1 ) 조건부 임포트 ( 1 ) 주절주절분노조절실패의식으흐름 ( 1 ) 패키지 ( 1 ) 프로젝트복사 ( 1 ) 플러그인 ( 1 )