[Android] 리스트 만들기 - RecyclerView

원준·2023년 7월 20일

Android Studio

목록 보기
16/40

RecyclerView ?

  • 대량의 데이터를 효율적으로 표시할 수 있는 View.
  • 기존 제공 ListView가 존재하지만, 커스터마이징과 효율성 측면에서 장점이 더 많은 View이다.
    • RecyclerView는 아래로 스크롤 할 때, 맨 위의 객체를 맨 아래로 이동시켜 재활용 하는 View.
    • ListVIew는 아래로 스크롤 할 때, 맨 위의 객체를 삭제하고 아랫부분에 대해 객체를 새로 생성한다.

그래서 사용은 ?

  • RecyclerView를 사용할려면 필수적으로 필요한것이 있는데, [Main RecyclerView] / [개별 정보 박스] / [개별 정보를 담을 Class] / [실제 생성 및 작동 Adapter Class] 가 필수이다.

1. Main RecyclerView 생성

  • Main Layout.xml 파일에서 사용할 RecyclerView를 생성한다.

2. RecyclerView에 들어갈 개별 정보 리스트를 만든다.

  • Layout에서 Layout Resource File을 만든다.

  • 개인적으로는 정보가 들어가고 사용되는 큰 기준의 이름을 사용해 이름_row라고 하는게 편했다.

  • CardView를 사용해서 한개의 박스를 쉽게 만들수 있다.

    • CardView를 꼭 사용할 필요는 없고, 원하는 크기만큼의 한개의 정보가 들어갈 공간을 만들어 주면 될 거같다.
    • 스크롤을 위, 아래로 할것이라면 좌우 공간은 상관없지만 상하의 크기는 꼭 설정하자.

3. 개별 정보에 들어갈 Class를 만든다.

  • Package를 model로 만들고 개별 정보에 들어갈 여러가지 정보들을 하나의 Class로 만들어 설정해 놓자.

    • 원래는 id, 날짜 등 여러가지 들어가는게 있으나, 공부용으로 작성한것이니, 간단하게 작성하자.
    package com.wonjun.simplememo.model;
    
      public class Memo {
         private String content;
    
         public Memo(String content) {
             this.content = content;
         }
    
         public String getContent() {
             return content;
         }
    
         public void setContent(String content) {
             this.content = content;
         }
     }

4. 개별 정보에 따라 화면을 만들 기능을 작성하자.

  • 간단히 말하면 Adapter를 생성해야한다.
  • Adapter는 화면을 보여주는 단계는 아직 아니고, 화면을 보여주기 위한 내부적 작업이라고 생각하면 편하다.
  • 우선 Class를 만들고 코드를 작성하기 시작하겠다. 이름은 위에 만든 클래스이름을 따라가는게 좋다.
  • Adapter를 생성하고 코드를 작성하는데 있어서 순서가 있는데 이는 코드안 주석으로 대체하겠다.
public class MemoAdapter extends RecyclerView.Adapter<MemoAdapter.ViewHolder> {//2. 어댑터 클래스 상속받기
                                                            // 안에 작성할 클래스는 자기 자신의 뷰홀더를 작성한다.

    // 상속받은 후 에러 발생 (작성 해야할 부분이 있기때문이다)
    // 3. 오버라이딩 함수 작성


    // 4. 클래스의 멤버변수 작성한다. 기본 2개는 필수.
    Context context; //어떤 엑티비티에서 수행되어야 하는지 알아야해서 필요하다.
    ArrayList<Memo> memoList;//데이터를 저장할 공간이 필요하다.

    // 5. 위의 멤버 변수를 셋팅할 생성자를 만들자.
    public MemoAdapter(Context context, ArrayList<Memo> memoList) {
        this.context = context;
        this.memoList = memoList;
    }
    
    // 6. 오버라이딩 함수 전부 작성하자.

    @NonNull
    @Override //리턴 타입을 내가 만든 뷰홀더로 변경하자.(기존의 리턴타입과는 조금 다름)
    public MemoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

            //memo_row.xml과 연결하는 코드
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.memo_row, parent, false);

        return new MemoAdapter.ViewHolder(view); //memo_row와 연결한 view를 넘겼기때문에 뷰홀더에서 findView가 가능하다.
    }

    @Override //화면과 데이터를 매칭시켜서, 실제로 데이터를 화면에 적용시키는 함수
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Memo memo = memoList.get(position);

        //자신이 만든 뷰홀더의 textView에 접근해서 텍스트를 변경하라.
        holder.txtContent.setText(memo.getContent());
    }

    @Override // 데이터의 갯수 함수 (행의 갯수)
    public int getItemCount() { //최대 보여줄 갯수
        return memoList.size();
    }




    // 1. 뷰홀더 클래스 만든다. (이너 클래스)
    // 해당 클래스에는 리스트에 들어갈 행화면 뷰들을 여기서 연결시킨다.
    public class ViewHolder extends RecyclerView.ViewHolder{

        // 행 화면에 있는 TextView를 작성
        TextView txtContent;
        
        //자동 완성 됨
        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            // 여기서 연결시킨다.
                //findView가 상속받지 않아서 사용할 수 가 없다.
                // itemView에서 사용가능하다.
            txtContent = itemView.findViewById(R.id.txtContent); //R이 자동완성이 안된다.
                                                //class를 import 받아와서 작성해야한다.
                                            // Main에서 되는 이유는 setContentView(R.layout.activity_main);를 통해 main을 연결시켰기 때문이다.

        }
    }
}

5. Main에서 사용해서 화면에 보여주기.

  • 이제 마지막 단계로 Main에서 코드를 작성을 하면 실제로 데이터를 받아 화면에 보여줄 수 있게 할 수 있다.
  • 매개 변수
//라사이클러뷰 는, 함께 사용하는 변수들이 있다.
     // MemoAdapter가 작성이 완료되면 이제 사용을 하기 시작한다.
 RecyclerView recyclerView;
 MemoAdapter adapter;
 ArrayList<Memo> memoList = new ArrayList<>(); //데이터를 담을 배열을 만든다.
  • onCreate() 내부 로직
//리사이클 찾기
recyclerView = findViewById(R.id.recyclerView);
    // 초기화 작업
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));


//버튼 누를시 작동
btnSave.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String content = editMemo.getText().toString().trim();

        if(content.isEmpty()){
            Snackbar.make(btnSave,
                    "메모 필수!",
                    Snackbar.LENGTH_SHORT).show();
            return;
        }

        // 메모 클래스 객채 생성 후 데이터를 저장한다.
        Memo memo = new Memo(content);

        // 메모가 여러개 이므로, 어레이리스트에 넣어준다.
        //memoList.add(memo);
        memoList.add(0, memo); //입력한 메모가 가장 최근의 위주로 보여주고 싶다.
            //불러올때 0부터 불러온다면, 애초에 0의 자리에 최근 데이터를 넣으면 되지 않나?

        //어뎁터에 만든 ArrayList와 Main액티비티를 넣는다.
        //adapter = new MemoAdapter(MainActivity.this, memoList);
        //recyclerView.setAdapter(adapter); //사이클에 적용
        
        editMemo.setText(""); //메모 작성 초기화

        // 코드를 최적화 할때 문제가 발생한다.
        // 데이터가 추가될때마다 업데이트가 안된다는것인데, 아래의 코드를 이용해 업데이트 하자.
        adapter.notifyDataSetChanged(); //데이터가 변경되었다고 알려줌.
    }
});


// 버튼 누를때 마다, 객체가 생성되면 메모리에 무한정 생기니
// 생성되는건 한번만 생성되도록 하자.
adapter = new MemoAdapter(MainActivity.this, memoList);
recyclerView.setAdapter(adapter);
profile
공부해보자

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

글 잘 봤습니다, 많은 도움이 되었습니다.

답글 달기