#1 RecyclerView

ADD·2021년 6월 29일
0
post-thumbnail

안드로이드 개발에 대해 처음 학습할 때, 굉장히 난감했던 뷰였다.
TextView, EditText, Button 등과 같이 단순한 뷰들은 구현과 활용의 난이도가 낮아 접근이 쉬웠지만,
RecyclerView 는 그렇지 않았다. Adapter 의 개념이 비교적 생소했기 때문이다.
해당 포스트에서는 Data Class 를 이용하여 RecyclerView 에 item 을 동적으로 삽입하는 것에 대해 서술한다.

Data Class

public class Memo {
    private String title;

    public String getTitle() {
        return title;
    }

    public Memo(String title) {
        this.title = title;
    }
}

해당 예제에서는 DB 를 사용하지 않지만, 이후 DB 와의 연결이 용이하도록 Data Class 를 생성해준다. 실제로 DB 와 연동하려면 id 값도 할당해주는 것이 좋다.

Adapter Class (My Adapter)

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private ArrayList<Memo> myList = new ArrayList<>();

    public MyAdapter(ArrayList<Memo> myList) {
        this.myList = myList;
    }

    @NonNull
    @org.jetbrains.annotations.NotNull
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(@NonNull @org.jetbrains.annotations.NotNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull @org.jetbrains.annotations.NotNull MyAdapter.ViewHolder holder, int position) {
        holder.textView.setText(myList.get(position).getTitle());
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        public ViewHolder(@NonNull @org.jetbrains.annotations.NotNull View itemView) {
            super(itemView);

            textView = itemView.findViewById(R.id.textView);
        }
    }
}

RecyclerView 를 구현할 때 가장 어려운 부분이 아닌가 싶다. 개발에 대해 처음 배웠을 때는 함수도 많고 코드 자체가 긴 편이라 크게 당황했던 기억이 난다.

먼저, 클래스를 생성하고 RecyclerView.Adapter 를 상속한다.
이후, 만들어 둔 Data Class 를 통해 생성할 객체를 담기 위한 ArrayList 를 초기화한다. 그 뒤, 생성자를 구현해준다.

해당 view 를 return 하기 위해 LayoutInflater 에 대해 정의한다. 이 때, 각 item 의 외관을 구현하기 위한 Layout 을 미리 구현해두어야 한다.

holder 를 통해 item_list 의 textView 를 참조할 수 있다. TextView 외에도 ImageView, Button 모두 가능하며, 심지어는 아이템 내부에 ViewPager 를 삽입하는 경우도 본 적 있다.

마지막으로 getItemCount 와 ViewHolder 에 대해 코딩한다.
getItemCount 의 경우, 함수명을 참 잘 지었다. 매우 직관적인 네이밍이다. ArrayList 가 가진 item 의 갯수를 반환하면 되는데, 마음 편하게 myList.size() 로 처리하면 된다.

ViewHolder 는 데이터를 Data class 를 통해 가공하고 뷰에 담기 전에 잠시 묶어두는 (Hold) 역할을 한다. 생성자를 구현하기 전에 item_list 의 뷰를 초기화 한 뒤, 생성자를 구현하고 생성자 단에서 참조하면 된다.

MainActivity

public class MainActivity extends AppCompatActivity {

    EditText editText;
    Button button;
    RecyclerView recyclerView;
    MyAdapter adapter;
    ArrayList<Memo> myList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (editText.getText().length() == 0) {
                    Toast.makeText(MainActivity.this, "입력하세요", Toast.LENGTH_SHORT).show();
                } else if (editText.getText().length() > 0) {
                    Memo memo = new Memo (editText.getText().toString());
                    myList.add(memo);
                    editText.setText("");
                    adapter.notifyDataSetChanged();
                }
            }
        });

    }
    public void initView() {
        editText = findViewById(R.id.editText);
        button = findViewById(R.id.button);
        recyclerView = findViewById(R.id.recyclerView);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
        recyclerView.setLayoutManager(linearLayoutManager);
        adapter = new MyAdapter(myList);
        recyclerView.setAdapter(adapter);
    }
}

(initView 함수를 통해 View 참조를 정리해준다. 해당 패턴이 주는 깔끔함이 너무 좋다.)

RecyclerView 에 꼭 필요한 것이 있다. Adapter Class 와 그 객체의 notifyDataSetChanged, LayoutManager.
adapter 를 연결하지 않고 컴파일 할 경우, 앱이 뻗진 않지만, 아무리 데이터를 추가해도 추가되지 않는다.
notifyDataSetChanged 의 경우도 마찬가지다. 앱이 뻗진 않지만, 동적 추가가 불가능하다.
LayoutManager 는 RecyclerView 가 갖는 형태를 결정한다. 해당 예제에서는 LinearLayout 을 사용했지만, Grid 등의 Layout 도 가능하다.

해당 예제에서는 버튼을 눌렀을 때, editText 에 입력된 Text 를 Data Class 를 통해 객체화하여 RecyclerView 에 동적으로 삽입해주고 editText 를 비운다.

0개의 댓글