춤추는 개발자

[AOS] Room + ViewModel + LiveData + RecyclerView (2) 본문

Android/study_til

[AOS] Room + ViewModel + LiveData + RecyclerView (2)

Heon_9u 2021. 6. 28. 17:02
728x90
반응형

 

 이번 포스팅에서는 간단한 layout구성을 시작으로 RecyclerView 제작을 위한 Adapter와 Note_item을 구현합니다. RecyclerView에 관한 설명은 이전 포스팅인 RecyclerView의 원리와 사용법을 참고하시기 바랍니다.

 

1. activity_main

 메인 페이지는 다른 View를 제외하고 RecyclerView만 구현합니다. 각 데이터들을 스크롤이 가능한 리스트 형태로 나타내며, 간단한 애니메이션 기능을 추가할 예정입니다.

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/note_item"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

2. note_item

 RecyclerView에서 데이터들을 나타내기 위한 View역할을 합니다. 즉, 데이터를 담는 형태라고 생각할 수 있습니다.

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp">

        <TextView
            android:id="@+id/text_view_priority"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:text="1"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"/>

        <TextView
            android:id="@+id/text_view_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="title"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            android:maxLines="1"
            android:layout_toStartOf="@id/text_view_priority"
            android:layout_alignParentStart="true"
            android:ellipsize="end"/>

        <TextView
            android:id="@+id/text_view_description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/text_view_title"
            android:text="Description"/>

    </RelativeLayout>

</androidx.cardview.widget.CardView>

 

 

3. NoteAdapter

 Adapter란 화면에 보여질 Note List를 RecyclerView에 바인딩시켜주는 역할을 합니다. note_item의 각 View에 실제 데이터들을 setting하며 ClickListener로 이벤트 처리가 가능합니다. 추후에는 ListAdapter를 상속받아서 Item과 View의 변화를 관찰하는 DiffUtil을 적용할 계획입니다.

 

package com.heon9u.aacproject;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
    private List<Note> notes = new ArrayList<>();

    @NonNull
    @Override
    public NoteHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.note_item, parent, false);

        return new NoteHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull NoteHolder holder, int position) {
        Note currentNote = notes.get(position);
        holder.textViewTitle.setText(currentNote.getTitle());
        holder.textViewDescription.setText(currentNote.getDescription());
        holder.textViewPriority.setText(String.valueOf(currentNote.getPriority()));
    }

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

    public void setNotes(List<Note> notes) {
        this.notes = notes;
        notifyDataSetChanged();
    }

    class NoteHolder extends RecyclerView.ViewHolder {
        private TextView textViewTitle;
        private TextView textViewDescription;
        private TextView textViewPriority;

        public NoteHolder(@NonNull View itemView) {
            super(itemView);
            textViewTitle = itemView.findViewById(R.id.text_view_title);
            textViewDescription = itemView.findViewById(R.id.text_view_description);
            textViewPriority = itemView.findViewById(R.id.text_view_priority);
        }
    }
}

 

4. MainActivity + RecyclerView

 마지막으로 Activity에서 RecyclerView를 생성하여 adapter를 적용합니다. 전에 구현한 onChanged 메서드에서 Toast대신 객체들의 변화를 adapter에 적용하는 메서드를 호출합니다. 이를 통해 List의 변화를 Adapter에 적용함으로써 데이터 값이 바뀐 상태를 UI에 실시간으로 나타낼 수 있게 됩니다.

 

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.widget.Toast;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);

    NoteAdapter adapter = new NoteAdapter();
    recyclerView.setAdapter(adapter);

    noteViewModel = new ViewModelProvider(this).get(NoteViewModel.class);
    noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>() {
        @Override
        public void onChanged(List<Note> notes) {
            adapter.setNotes(notes);
        }
    });
}

 

 

 이렇게 ViewModel과 Observer를 활용함으로써 데이터 값의 변화를 바로 UI에 적용할 수 있습니다. 만약 ViewModel을 사용하지 않는 경우, List를 매번 Adapter에 setting하는 코드가 추가적으로 필요합니다. 게다가 변화가 없는 경우에는 해당 작업이 불필요하므로 자원을 낭비하게 됩니다.

 

 다음 포스팅에서는 Note를 추가 및 편집하는 Activity를 제작하도록 하겠습니다.

728x90
반응형