ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [RecyclerView] 기본 RecyclerView 만들기
    Android 2017. 9. 19. 14:33


     · 기본(세로) RecyclerView 만들기 


    이제는 새로나왔다고 하기도 어려운 RecyclerView를 차근차근 순서대로 만들어 볼것이다.



      1   RecyclerView 란?


    RecyclerView는 과거의 ListView에서 좀 더 성능과 유연성이 개선된 View라고 할 수 있다.

    나도 가로로된 List를 만들기 위해 ListView를 커스텀해서 사용했다가,

    RecyclerView에서 기본으로 제공해주는 기능이어서 바꿔보기도 했다.


    일단 사용을 하려면 Support Library v7을 추가해서 사용해야 하며 그 내용은 아래에서 살펴보겠다.


      2   순서대로 차근차근 만들어보장


    스크린샷 같은 리스트를 아무것도 없는 프로젝트에서 처음부터 차근차근 만들어 볼것이다.

    ListView와 똑같이 생겼지만 RecyclerView로 만들어져있다.


     1) gradle 라이브러리 추가 


    첫번째로 위에서 언급한것과 같이 RecyclerView를 사용하기 위해  build.gradle 파일에 

    라이브러리를 아래와 같이 추가해준다.


    버전은 각자의 프로젝트 환경과 맞추어준다.

    compile 'com.android.support:recyclerview-v7:24.2.1'


     2) 레이아웃 파일 작성 


    레이아웃 파일은 두가지가 필요하다.

    1. 리스트가 보여질 xml 파일

    - item들을 담고 있는 list 레이아웃이다.


    2. 리스트 안에 들어갈 item.xml 파일

    - list안에 들어갈 한개의 항목(item)에 대한 레이아웃이다.


       vertical_recycler_view.xml

    <?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.support.v7.widget.RecyclerView
    android:id="@+id/vertical_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

    </LinearLayout>

       vertical_recycler_items.xml

    <?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="wrap_content"
    android:orientation="horizontal">

    <RelativeLayout
    android:background="#eaeaea"
    android:layout_width="match_parent"
    android:layout_margin="8dp"
    android:layout_height="wrap_content">

    <ImageView
    android:id="@+id/vertical_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@mipmap/ic_launcher" />

    <TextView
    android:id="@+id/vertical_description"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_toRightOf="@id/vertical_icon"
    android:text="~번째 데이터" />

    </RelativeLayout>

    </LinearLayout>

    이정도가 기본이 될 수 있는 리스트의 레이아웃일 것이다.



     3) Acticity 작성 


    레이아웃을 작성했으니 코드를 작성해보자.

    여기서는 총 4가지의 class를 사용할것이다.

    세로로 늘어진 형태의 리스트를 만들것이라서 네이밍은 Vertical로 통일하였다.


    1. Acticity.java

    - 프로젝트를 생성하면 처음에 만들어져있는 MainActivity.java 예제에서는 VerticalRecyclerView.java로 네이밍되있다.


    2. VerticalData.java

    - 리스트 item안에 들어갈 내용이다. 위의 레이아웃<vertical_recycler_items.xml> 에서 ImageView와 TextView를 만들어줬는데

    그부분에 들어갈 데이터들을 관리할것이다.


    3. VerticalViewHolder.java

    - ViewHolder를 상속받는 클래스이다. ListView에서도 사용했던 기능인데, RecyclerView에서는 사용을 강제하고 있다.

    예를들어 데이터가 100개라면 ViewHolder를 구현하지 않았을 때 ImageView, TextView를 100개를 생성할 것이다. 물론 100개는 문제가 없을 수도 있지만 그 수가 많아지고 게다가 이미지라면 메모리의 문제가 발생 할 것이다. 

    그 문제를 방지 하기 위해서 ViewHolder는 디바이스에 현재 보여지고 있는 아이템만을 바인딩 시켜 사용하게끔 한다. 

    리스트에서 보여지고 있는 ImageView, TextView 만 생성하여 사용하다가, 스크롤을 내리는 순간 보이지 않게 되는 Item View를 재활용하여 새롭게 보이는 데이터에 집어넣어 사용한다.


    4. VerticalAdapter.java

    - 리스트의 데이터를 관장하는 Adapter이다. RecyclerView와 Data사이에서 List에 데이터를 넣어주고 꾸며주는 역할을 담당한다.


    코드는 위의 순서와 상관없이 내가 이해하기 쉬운 순서대로 작성할 것이다.


       VerticalData.java

    class VerticalData {

    private int img;
    private String text;

    public VerticalData(int img, String text){
    this.img = img;
    this.text = text;
    }

    public String getText() {
    return this.text;
    }

    public int getImg() {
    return this.img;
    }
    }

    item 레이아웃에 들어갈 데이터 두가지이다.

    img 는 'R.drawable.img' 형식을 받을것이고

    String 은 그 옆에 들어갈 text를 받을것이다.


       VerticalViewHolder.java

    class VerticalViewHolder extends RecyclerView.ViewHolder {

    public ImageView icon;
    public TextView description;

    public VerticalViewHolder(View itemView) {
    super(itemView);

    icon = (ImageView) itemView.findViewById(R.id.vertical_icon);
    description = (TextView) itemView.findViewById(R.id.vertical_description);

    }
    }

    VerticalViewHolder 는 RecyclerView.ViewHolder를 상속받는다.

    생성자로는 View를 전달받는데 여기서 전달받을 itemView는 <vertical_recycler_items.xml> 이다.

    itemView를 받아 각각 바인딩해준다.


    보통 ViewHolder 클래스는 관리 측면에서 다음에 만들어줄 Adapter 클래스 안에 inner 클래스로 작성하는게 좋다고 한다.

    여기서는 따로 작성하였다.


       VerticalViewHolder.java

    class VerticalAdapter extends RecyclerView.Adapter<VerticalViewHolder> {

    private ArrayList<VerticalData> verticalDatas;

    public void setData(ArrayList<VerticalData> list){
    verticalDatas = list;
    }

    @Override
    public VerticalViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    // 사용할 아이템의 뷰를 생성해준다.
    View view = LayoutInflater.from(parent.getContext())
    .inflate(R.layout.vertical_recycler_items, parent, false);

    VerticalViewHolder holder = new VerticalViewHolder(view);

    return holder;
    }

    @Override
    public void onBindViewHolder(VerticalViewHolder holder, int position) {
    VerticalData data = verticalDatas.get(position);

    holder.description.setText(data.getText());
    holder.icon.setImageResource(data.getImg());

    }

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

    여기서 부터 복잡함이 시작된다. 

    일단 Adapter는 RecyclerView.Adapter를 상속받으며 제네릭으로 위에서 작성한 VerticalViewHolder를 준다.

    그리고 onCreateViewHolder(), onBindViewHolder(), getItemCount() 를 오버라이드 받는다.


    처음으로 보이는 setData()는 Adapter에 전달해서 사용할 List형의 데이터를 세팅한다. 이부분은 다음 코드에서 확인할 수 있다.


    onCreateViewHolder()는 아이템을 생성하여 ViewHolder에 집어넣는 역할을 한다. 여기서 전달해주는 view가 < VerticalViewHolder.java >에서 사용되는 itemView가 된다. 

    즉, < vertical_recycler_items.xml > 를 받아와서 홀더에 넣고 계속 돌려쓴다.


    onBindViewHolder()는 onCreateViewHolder에서 리턴한 ViewHolder에다가 데이터를 세팅해줄 수 있다.

    여기서는 verticalDatas.get(position) 을 이용해 데이터를 가져오고 (여기서의 position은 list item의 순서이다. 시작은 0)

    holder에서 view들을 꺼네 데이터들을 세팅해준다.


    getItemCount()는 보통 item의 총 갯수를 반환하게 한다.


       VerticalRecyclerView.java


    리스트를 가지고 있는 액티비티이다.

    public class VerticalRecyclerView extends AppCompatActivity {

    private RecyclerView mVerticalView;
    private VerticalAdapter mAdapter;
    private LinearLayoutManager mLayoutManager;

    private int MAX_ITEM_COUNT = 50;

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

    // RecyclerView binding
    mVerticalView = (RecyclerView) findViewById(R.id.vertical_list);

    // init Data
    ArrayList<VerticalData> data = new ArrayList<>();

    int i = 0;
    while (i < MAX_ITEM_COUNT) {
    data.add(new VerticalData(R.mipmap.ic_launcher, i+"번째 데이터"));
    i++;
    }


    // init LayoutManager
    mLayoutManager = new LinearLayoutManager(this);
    mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); // 기본값이 VERTICAL

    // setLayoutManager
    mVerticalView.setLayoutManager(mLayoutManager);

    // init Adapter
    mAdapter = new VerticalAdapter();

    // set Data
    mAdapter.setData(data);

    // set Adapter
    mVerticalView.setAdapter(mAdapter);

    }
    }

    setContentView()로 RecyclerView를 정의한 레이아웃을 set하고 RecyclerView를 binding 한다.

    그리고 리스트에 넣어줄 데이터를 추가할것이다. 여기서는 MAX_ITEM_COUNT 만큼 VerticalData를 생성하는데 이미지는

    기본으로 제공되는 ic_launcher 아이콘을 사용했고 총 50개의 아이템을 생성한다.


    선언된 mVerticalView에 LayoutManager를 set해주어야 한다. LayoutManager는 RecyclerView에서 사용하는 레이아웃을 관리하기 위한것이다. LayoutManager를 이용해서 가로형, 세로형, Grid형 등을 만들어 줄 수 있다. 

    지금은 기본형 리스트니까 setLayoutManager(new LinearLayoutManager(this)); 로 해줘도 괜찮다.


    mAdapter를 생성해주고 setData()를 이용해서 좀전에 만든 50개짜리 데이터를 set해준다.

    이제 좀전에 생성해준 Adapter는 ArrayList형의 데이터를 가지고 있고 그 데이터를 List에 뿌려줄 수 있다.


    그리고 RecyclerView에 Adapter를 set해주면 기본적인 리스트가 완성된다.



      3   마무리


    간단하게 RecyclerView를 활용한 리스트를 완성해보았다.

    기본 토대가 완성되었으니 다음에는 좀 더 이것저것을 만들어 볼 수 있을것이다!


    예제 파일은 아래 링크에 공유해두었다.



    + 설명이 잘못된점이 있다면 댓글로 피드백 부탁드립니다!



    댓글

Designed by Tistory.