SW 공부노트

[안드로이드/자바] RecyclerView 구현하기 본문

안드로이드/안드로이드 실습

[안드로이드/자바] RecyclerView 구현하기

요빈 2022. 7. 21. 16:38

안드로이드 앱을 개발하다 보면 다양한 View를 사용하게 된다. 그중 처음으로 사용해본 것이 ListView(리스트뷰)였는데 최근에 리스트뷰의 대부분의 기능을 RecyclerView(리사이클러뷰)로 할 수 있다는 것을 알게 되어 직접 구현해보았다.

 

RecyclerView는 ListView의 개선된 형태로 목록의 뷰는 ViewHolder로 표현되며 각 ViewHolder는 View를 사용하여 각 항목을 표시하는 역할을 한다.

ViewHolder 객체는 Adapter에서 관리하며 Adapter는 필요에 따라 ViewHolder를 만들어 onBindViewHolder()를 호출함으로써 데이터에 바인딩한다.

View를 채울 때 LayoutManager가 필요한데, LinearLayoutManager 또는 GridLayoutManager를 쓰거나 직접 구현하여 사용할 수 있다. 


리사이클러 뷰는 RecyclerView, RecyclerAdapter, 아이템을 담을 ItemView, Data 클래스로 구성되어 있다.

각 구성요소들을 차례대로 살펴보며 진행해보도록 하겠다.

1. RecyclerView 레이아웃 만들기

gradle 파일 수정 후, 첫 번째로 RecyclerView가 탑재된 레이아웃 파일을 만들어 주었다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
</LinearLayout>

activity_recycler.xml

2. ItemView(아이템 레이아웃) 만들기

ItemView는 리사이클러뷰 내에 아이템을 어떤 식으로 배치할 것인지 레이아웃을 지정해주는 파일이다.

이번 예시에서는 댓글 형식을 참고하여 레이아웃을 만들어주었다.

따라서 댓글내용, 작성자, 작성 시간을 담는 TextView를 추가하였으며 각 컴포넌트 별 text값 및 상세 layout 속성들은

사용자 편의에 맞게 지정해주면 된다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_margin="5dp">
    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="댓글 내용"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation ="horizontal">
        <TextView
            android:id="@+id/writer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:text="작성자"
            android:textSize="11sp"
            android:textColor="#B1B1B1"/>
        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:layout_marginLeft="10dp"
            android:text="작성 시간"
            android:textSize="11sp"
            android:textColor="#B1B1B1"/>
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="10dp"
        android:background="#cfcfcf"/>
</LinearLayout>

recycler_item.xml

3. RecyclerView Adapter 클래스 만들기

Adapter는 RecyclerView.Adapter를 상속받아 구현하고, ViewHolder는 RecyclerView.ViewHolder를 상속받아 구현한다.

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {

    private ArrayList<CommentItem> CommentList;

    @NonNull
    @Override
    public MyRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyRecyclerAdapter.ViewHolder holder, int position) {
        holder.onBind(CommentList.get(position));
    }

    public void setList(ArrayList<CommentItem> list){
        this.CommentList = list;
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        return CommentList.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        TextView content;
        TextView writer;
        TextView time;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            content = (TextView) itemView.findViewById(R.id.content);
            writer = (TextView) itemView.findViewById(R.id.writer);
            time = (TextView) itemView.findViewById(R.id.time);
        }

        void onBind(CommentItem item){
            content.setText(item.getContents());
            writer.setText(item.getWriter());
            time.setText(item.getTime());
        }
    }
}

MyRecyclerAdapter.java

4. Data 클래스 만들기

댓글 정보를 담을 Data클래스를 생성해준다.

public class CommentItem {
    
    String contents;
    String writer;
    String time;

    public CommentItem(String contents, String writer, String time) {
            this.contents = contents;
            this.writer = writer;
            this.time = time;
        }
    public String getContents() { return contents; }
    public String getWriter() { return writer; }
    public String getTime() { return time; }

    // public void setContents(String contents) { this.contents = contents }
    // 위와 같이 설정 메소드 작성 가능
}

CommentItem.java

5. Activity 파일에서 View 적용하기

RecyclerView가 들어갈 Activity 파일에서 Adapter와 LayoutManager를 연결해준다. 

그 후 임의 데이터를 넣어 구현이 제대로 되었는지 확인할 수 있도록 하였다.

Adapter에 데이터가 추가되거나 삭제되는 등의 변경사항이 발생한 경우 Adapter의 notifyDataSetChanged()를 호출하여 데이터가 변경되었음을 알려야 한다. 

해당 예시에서는 MyRecyclerDapter 내에 notifyDataSetChanged()를 호출하는 메소드인 setList()를 따로 작성하였다.

public class RecyclerActivity extends AppCompatActivity {

    MyRecyclerAdapter recyclerAdapter;
    ArrayList<CommentItem> commentItems = new ArrayList<CommentItem>();
    RecyclerView recyclerView = null;
    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler);
        
        recyclerView = findViewById(R.id.recyclerView);
        
        /* Adapter 초기화 */
        recyclerAdapter = new MyRecyclerAdapter(); 
        
        /* RecyclerView 초기화 */
        recyclerView.setAdapter(recyclerAdapter); 
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        
        commentItems.add(new CommentItem("댓글 예시", "user1","2022-07-17 15:41"));
        commentItems.add(new CommentItem("댓글 내용 입니다.", "user2","2022-08-20 05:19"));
        commentItems.add(new CommentItem("댓글 내용", "user3","2022-11-05 21:05"));
        recyclerAdapter.setList(commentItems);
        }
}

RecyclerActivity.java

다음은 최종 실행 결과이다.

 

 

* 개인적으로 공부하며 배운 부분을 정리한 글이므로 설명이 잘못되거나 불필요한 코드가 있을 수 있습니다.