본문 바로가기
안드로이드

[안드로이드 #3] RecyclerView (상)

by algosketch 2021. 3. 31.

 이번 강의에 사용된 이미지용 xml

bubble.xml
0.00MB
profile.xml
0.00MB

 이번에는 RecyclerView 하나만 다뤄보도록 하겠습니다. RecyclerView와 비슷한 역할을 하는 View로 ListView가 있습니다. 하지만 ListView는 커스터마이징이 불가능하고 이미 만들어져 있는 것만 사용할 수 있습니다. ListView는 안 예뻐요. 그 밖에도 뷰를 재사용하는 RecyclerView 의 특징이 있기 때문에 대부분 RecyclerView를 이용한다고 생각하시면 됩니다. ListView의 이름에서 예상하셨겠지만 ListView나 RecyclerView는 같은 형식의 데이터 여러 개를 출력시켜주는 View입니다.

 기존의 코드에서 덧붙이는 것보다 새로운 화면에서 만드는 것이 좋아보입니다. 우선 새 모듈을 하나 만들어 주세요.

new module 1
new module 2
new module 3

 액티비티는 Empty Activity -> 기본 설정 그대로 만들어 줍니다.

 Recyclerview를 사용하려면 두 가지 준비물이 필요합니다. 첫 째로 각각의 데이터를 어떻게 화면에 보여줄 건지 item layout 을 만들어야 합니다. 둘 째로 각 데이터들을 화면에 배치하는 코드로 Adapter 클래스를 구현해야 합니다. 그리고 이 RecyclerView가 내가 정의한 이 Adapter 방식으로 사용한다고 알려줘야 합니다.

 일단 RecyclerView를 화면에 배치해보겠습니다. (activity_main.xml)

RecyclerView 1

 기존에 있던 Hello, World 코드를 지우고 RecylerView를 만들어 주세요. 여기서 layoutManager를 지정해줘야 합니다. (코틀린 코드로도 지정할 수 있습니다.)layoutManager는 이 RecyclerView를 어떤 방식으로 배치할 지 결정합니다.

 이제 첫 번째 준비물을 만들어야 합니다. layout 폴더를 우클릭하여 New -> Layout Resource File 을 선택합니다.

item_recylerview 1

 대충 이름을 지어줍니다. 프로젝트에서는 이름 대충 지으면 안 됩니다. 아 근데 IDE 덕분에 리펙터링이 쉬우니 대충 지으셔도 됩니다(?) item_recylerview.xml

item_reclerview 2

 하나의 데이터 덩어리에 대해 어떤 식으로 배치할 건지 여기에 그려주시면 됩니다. 저는 이미지 하나와 텍스트 하나를 출력하면 될 것 같습니다. 참고로 TextView는 background 속성으로 배경을 지정해줬습니다.

 그 다음엔 클래스 하나를 만들어 줍니다. (ChattingAdaper.kt)

adapter 1

23.09.05 각주 - 해당 코드에서는 inner class를 사용할 이유가 없으므로, inner 키워드를 빼는 게 좋습니다. 이 코드는 아니지만 inner class는 메모리 누수를 발생시킬 가능성이 있습니다.

 음... 이거는 구현하기 나름이지만 기본적으로는 위와 같은 구조를 갖는다고 보시면 되겠습니다. Adapter를 상속 받아 구현해야 하는데, Adapter는 ViewHolder를 필요로 합니다. 이 예제에서는 Message 클래스 없이 그냥 String을 써도 됐었는데 보통 ViewHolder는 VO클래스(위에서는 Message 클래스)를 필요로 합니다. 만약 채팅 메시지가 텍스트 뿐만 아니라 사진도 보낼 수 있었다면 Message는 클래스가 아니라 인터페이스로 만들고 이것을 상속하는 두 개의 클래스를 만들어야 합니다. 만약 클래스 상속이나 인터페이스 구현이 익숙하지 않다면 어렵게 느껴질 수 있습니다. 해당 내용은 "다형성"이라는 키워드로 검색하시면 쉽게 내용을 찾을 수 있습니다.

 Adapter 클래스를 상속하면 반드시 3개의 메서드를 오버라이딩 해야 합니다. 그게 위 코드에서 구현한 3개입니다. 가장 쉬운 getItemCount() 부터 설명하자면 이 메서드는 출력할 데이터의 개수를 반환합니다. onCreateViewHolder()는 아까 만들어둔 레이아웃 item_recyclerview 와 연결해주는 역할을 합니다. onBindViewHolder()는 화면(View)에 출력될 값(메시지)을 지정해 줍니다.

 ViewHolder 클래스에서는 아까 만든 item_recyclerView에 있는 View를 가져옵니다.

MainAcitivity.kt

 이제 메인 액티비티에서 RecyclerView를 받아서 미리 만들어둔 아답터를 연결해주면 끝입니다.

result

 우리가 만든 RecyclerView는 이렇게 랜더링 됩니다.

 나중에 작성할 RecyclerView (하) 를 합쳐도 지난 스터디보다 분량이 훨씬 적을 것이라 생각합니다. 내용은 적지만 아마 지난번보다 쉽지는 않을 것이니 코드를 수정해보며 익숙해지는 게 좋을 것 같습니다.

...

 아니 그래도 분량이 너무 적은 것 같은데 이쯤에서 보너스 내용을 풀자면, 강의에 준비하는 이미지 xml 파일을 제가 직접 코드로 그린 것들입니다. 이전에 이미 말했는지 기억이 안 나네요. 아마 안 말한 것 같은데...

xml 1
xml 2

 drawable 위치에서 New > Drawable Rosource File 을 만들면 <selector ...>...</selector> 코드가 생성됩니다. selector를 지우고 shape를 써주면 가장 기본적인 모양을 그릴 수 있습니다. 만들 수 있는 건 사각형, 원, 선 정도입니다. 크기 조절, 원하는 모서리 원하는 만큼 둥글게, 선 너비, 색깔 등을 적절히 설정하고 배치해서 앱 만들 때 필요한 꽤 많은 아이콘이나 배경을 만들 수 있습니다.

 하나의 모양만 사용한다면 <xml 1>처럼 바로 shape 태그를 사용하시면 됩니다. 만약 xml 2 처럼 여러 그림을 겹쳐서 사용하고 싶다면 최상단을 layer-list 태그로 감싸고 그 안쪽에 각각의 shape들도 item 태그로 감싼 후 사용하시면 됩니다. 두 번째 아이템부터는 item 속성에 top="24dp" 이런식으로 설정할 수 있는데, 이 item의 상단이 첫 번째 아이템의 상단보다 24dp만큼 아래에 있다는 뜻입니다. 세 번째 아이템을 만들어도 마찬가지로 첫 번째 아이템이 기준이 되며, 음수값도 지정이 가능합니다.

 원은 크기를 조절하여 타원을 만들 수 있습니다. 각각의 도형은 회전이 가능하고 겹칠 수도 있기 때문에 창의적으로 많은 것들을 만들 수 있습니다. 저도 커리큘럼으로 공부한 건 아니고 프로젝트 하다가 조금씩 찾아보고 익힌 게 꽤 유용하네요.

 다음 글도 RecyclerView 인데 주로 아이템 각각에 대해 다르게 다르게 배치하는 방법, 데코레이션에 대한 내용입니다. 카카오톡 채팅방처럼 내 채팅은 오른쪽에 배치하면서 다른 사람의 채팅은 왼쪽으로 배치하는 게 하나의 RecyclerView로 가능합니다.