Android(Java) - RecyclerView Adapter - 리스트를 화면에 출력하기

 

아래의 예제 앱은 깃허브에서 확인 가능합니다

https://github.com/luvris2/Android-RecyclerViewTest-App

 

GitHub - luvris2/Android-RecyclerViewTest-App

Contribute to luvris2/Android-RecyclerViewTest-App development by creating an account on GitHub.

github.com


RecyclerView Adapter 필요한 파일 추가

  • 새로운 클래스를 생성 할 자바 파일 추가

 

  • RecyclerView Adapter와 연결될 레이아웃 파일 추가
    • 경로 : res - layout
    • new - Layout Resource File

 

  • Layout Resource File 추가
    • File name : 원하는 이름으로 설정, 포스팅에서는 adapter_row로 지정
    • Root element : LinearLayout


레이아웃 UI 설계 (adapter_row.xml)

  • 간단한 테스트를 위한 텍스트뷰
  • 리니어 레이아웃은 layout_height가 wrap_content여야 여러개의 데이터를 출력 할 수 있음


레이아웃 UI 설계 (activity_main.xml)

  • 리스트를 보여줄 리사이클러뷰


RecyclerView Adapter 클래스 생성하는 방법

1. 클래스에 RecyclerView.Adapter 상속

public class Adapter extends RecyclerView.Adapter {
}

2. 추상 메소드와 생성자 정의

public class Adapter extends RecyclerView.Adapter {

    public adapter() {
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }
}

3. VeiwHolder 클래스 생성

  • RecyclerView.ViewHolder 클래스 상속
  • 생성자 정의 후 뷰를 연결 시키는 코드 작성
  • 부분 코드
public class ViewHolder extends RecyclerView.ViewHolder {

    // 3. 생성자에 뷰와 연결시키는 코드 작성
    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        // 코드 작성
}

 

  • 전체 코드
public class Adapter extends RecyclerView.Adapter {

    public Adapter() {
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }
    
    public class ViewHolder extends RecyclerView.ViewHolder {

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // 코드 작성
        }
    }
}

4. 클래스의 멤버 변수와 생성자 정의

  • 액티비티의 정보를 담을 context
  • 여러개의 리스트를 출력할 ArrayList 배열 정의
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
    Context context;
    List<String> testList;

    public Adapter(Context context, ArrayList<String> testList) {
        this.context = context;
        this.testList = testList;
    }
}

5. 현재 클래스의 타입을 3번에서 생성한 ViewHolder 클래스로 변경

  • 부분 코드
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
    // 상속 클래스의 타입을 부모 클래스.뷰홀더로 변경
    public class ViewHolder extends RecyclerView.ViewHolder {

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // 코드 작성
        }
    }
}

 

  • 전체 코드
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

    Context context;
    List<String> testList;

    public Adapter(Context context, ArrayList<String> testList) {
        this.context = context;
        this.testList = testList;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
    
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // 코드 작성
        }
    }
}

6. RecyclerView.ViewHolder 메소드 구현 후 현재 클래스의 이름으로 변경

  • 클래스 이름 변경
    • RecyclerView.ViewHolder > 현재클래스이름.ViewHolder
  • 리사이클러뷰에 보여질 레이아웃 설정
    • LayoutInflater.from(parent.getContext()).inflate(R.layout.~~~, parent, false);
    • R.layout 부분에 레이아웃이 설정된 파일 이름 기재
  • return
    • 현재 클래스로 이름을 변경하였으므로 리턴 또한 현재 클래스의 이름으로 반환
  • 부분 코드
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

    // 6. RecyclerView.ViewHolder 메소드 구현, 현재 클래스 이름으로 변경 -> Adapter.ViewHolder
    @NonNull
    @Override
    public Adapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.~~~, parent, false);
        return new Adapter.ViewHolder(view);
    }
    
}

 

  • 전체 코드
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

    Context context;
    List<String> testList;

    public Adapter(Context context, ArrayList<String> testList) {
        this.context = context;
        this.testList = testList;
    }

    // 6. RecyclerView.ViewHolder 메소드 구현, 현재 클래스 이름으로 변경 -> Adapter.ViewHolder
    @NonNull
    @Override
    public Adapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.~~~, parent, false);
        return new Adapter.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
    
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // 코드 작성
        }
    }
}

7. onBindViewHolder의 파라미터를 현재의 클래스 이름.ViewHolder으로 변경

  • RecyclerView.ViewHolder > 현재의 클래스 이름.ViewHolder
  • 부분 코드
public class Adapter extends RecyclerView.Adapter {

    // 메모리에 있는 데이터를 화면에 표시하는 메소드
    // 7. 파라미터의 RecyclerView.ViewHolder, 현재 클래스 이름으로 변경 -> adapter.ViewHolder
    @Override
    public void onBindViewHolder(@NonNull Adapter.ViewHolder holder, int position) {
        // 코드 작성
    }
}

 

  • 전체 코드
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

    Context context;
    List<String> testList;

    public Adapter(Context context, ArrayList<String> testList) {
        this.context = context;
        this.testList = testList;
    }

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

    // 메모리에 있는 데이터를 화면에 표시하는 메소드
    // 7. 파라미터의 RecyclerView.ViewHolder, 현재 클래스 이름으로 변경 -> Adapter.ViewHolder
    @Override
    public void onBindViewHolder(@NonNull Adapter.ViewHolder holder, int position) {
        // 코드 작성
    }

    @Override
    public int getItemCount() {
        return 0;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // 코드 작성
        }
    }
}

8. getItemCount 메소드의 리턴 값 정의

  • 화면에 보여질 데이터의 수 지정, 리스트의 모든 데이터 출력은 size 함수 이용
  • 부분 코드
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
    // 리턴 값 정의
    @Override
    public int getItemCount() {
        return testList.size();
    }
}

 

  • 전체 코드
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

    Context context;
    List<String> testList;

    public Adapter(Context context, ArrayList<String> testList) {
        this.context = context;
        this.testList = testList;
    }

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

    @Override
    public void onBindViewHolder(@NonNull Adapter.ViewHolder holder, int position) {
        // 코드 작성
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // 코드 작성
        }
    }
}

RecyclerView Adapter 작동 원리

  • MainActivity에서 Adapter 호출
  • Adapter 생성자 정의
  • Adapter의 ViewHolder 생성 및 레이아웃 파일과 매칭
  • Adapter의 getItemCount 메소드 호출
    • 화면에 보여질 데이터의 갯수 확인
  • Adapter의 ViewHolder 클래스 호출
    • 객체를 정의하는 곳 (ex: TextView txt = findViewById(R.id.textView);)
  • Adapter의 onBindViewHolder 메소드 호출
    • 객체를 화면에 표시 (ex: holder.setText(StringVar);)

MainActivity를 RecyclerView와 연결시키는 방법

  • 부분 코드
// 리사이클러뷰 객체 생성
RecyclerView rv = findViewById(R.id.recyclerView);

// 리사이클러뷰 화면 설정
rv.setHasFixedSize(true);
rv.setLayoutManager(new LinearLayoutManager(MainActivity.this));

// 리사이클러뷰에 보여질 리스트 데이터 설정
ArrayList<String> testList = new ArrayList<>();
testList.add("Hello");
testList.add("World!");

// 만들어두었던 Adapter 클래스 객체화
viewAdapter = new Adapter(MainActivity.this, testList);

// 리사이클러뷰에 데이터 입력, 리스트 화면에 출력
recyclerView.setAdapter(viewAdapter);

 

  • 전체 코드
public class MainActivity extends AppCompatActivity {
	// 리사이클러뷰 정의
    RecyclerView recyclerView;
    // 위에서 만들어두었던 Adapter 클래스 호출
    Adapter viewAdapter;

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

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

        viewAdapter = new Adapter("Hello");

        recyclerView.setAdapter(viewAdapter);
    }
}

리사이클러뷰를 통해 리스트 출력 구현해보기

기능 설계

  • 앱을 실행하면 설정해두었던 "Hello"와 "World!"를 리스트로 출력
  • RecyclerView id : recyclerView
  • TextView id : textView
  • ArrayList : testList

 

소스 코드

  • MainActivity.java
public class MainActivity extends AppCompatActivity {

    RecyclerView recyclerView;
    Adapter viewAdapter;

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

        ArrayList<String> testList = new ArrayList<>();
        testList.add("Hello");
        testList.add("World!");

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

        viewAdapter = new Adapter(MainActivity.this, testList);
        recyclerView.setAdapter(viewAdapter);
    }
}

 

  • Adapter.java
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
    Context context;
    List<String> testList;

    public Adapter(Context context, ArrayList<String> testList) {
        this.context = context;
        this.testList = testList;
    }

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

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        String strData = testList.get(position);
        holder.txt.setText(strData);
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView txt;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            txt = itemView.findViewById(R.id.textView);
        }
    }
}

실행 화면

  • 화면 실행시 리사이클러뷰에 리스트 출력