RecyclerView는 ViewGroup의 서브 클래스로, ListView 보다 더 편리하고 유연하게 만들어졌다.
하나의 자식 View 객체를 각 항목당 배치하여 리스트를 보여준다는 것은 ListView와 같다.

다른 점은 ListView는 직접 코딩 하지 않으면 모든 항목을 한 번에 보여주지만,
RecyclerView는 별도의 코딩 없이 화면을 채울 정도의 View 객체만 생성 후
화면이 스크롤 되면 화면을 벗어나는 View를 재활용하여 다음 View 객체를 보여준다.

RecyclerView는 LayoutManager가 함께 있어야 움직이고, View 객체를 얻으려면 Adapter뿐만 아니라 ViewHolder가 반드시 필요하다.
그리고 자신이 View 객체를 생성하지 않고 Adapter를 통해 ViewHolder 객체를 생성하고 사용한다.

0. RecyclerView 라이브러리를 추가한다.
Library dependency로 recyclerview-v7 를 찾아서 추가하거나
build.gradle(Module:app)에 직접 추가한다.

dependencies {
    compile 'com.android.support:recyclerview-v7:25.1.0'


1. RecyclerView를 layout 안에 위치시킨다. (layout자체를 RecyclerView로 해서 사용하면 오류가 발생한다.)

<!--activity_main.xml-->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout ...>

    <android.support.v7.widget.RecyclerView
        ...
        android:id="@+id/view_recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>
<!--ERROR-->
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
    ...
    android:id="@+id/view_recycler"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</android.support.v7.widget.RecyclerView>


2. 리스트의 항목이 보여줄 View를 만든다.

<!--custom_recycler_list_item.xml-->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout ...
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <TextView
        android:text="항목"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:id="@+id/tv_item_category"
        android:layout_alignParentLeft="true"
        android:paddingLeft="15dp"
        android:gravity="left|center_vertical"/>

    <TextView
        android:text="내용"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:id="@+id/tv_item_name"
        android:layout_toRightOf="@+id/tv_item_category"
        android:paddingLeft="15dp"
        android:gravity="left|center_vertical"
        />
</RelativeLayout>

Layout의 height을 wrap_content로 설정하고 객체들의 높이를 지정해주어야 리스트 항목들이 제대로 보인다.

3. 데이터 정보를 갖는 class를 만든다.

public class class RecycleItem {
    private UUID mId;
    private String mCategory;
    private String mName;

    public RecycleItem(UUID id) {
        mId = id;
    }

    public RecycleItem() {
        this(UUID.randomUUID());
    }

    public UUID getId() {
        return mId;
    }

    public void setId(UUID id) {
        mId = id;
    }

    public String getCategory() {
        return mCategory;
    }

    public void setCategory(String category) {
        mCategory = category;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

}


4. RecyclerView를 사용할 Activity에 RecyclerView 객체를 참조한 후에 LayoutManager를 설정해준다.

public class RecyclerActivity extends AppCompatActivity {

    private RecycleAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.view_recycler);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }
}

LayoutManager는 리스트 항목의 배치를 어떻게 할지 정하고 스트롤 동작도 정의한다.
수평/수직 리스트 LinearLayoutManager, 그리드 리스트 GridLayoutManager,
높이가 불규칙적인 그리드 리스트 StaggeredGridLayoutManager를 기본적으로 제공한다.
이 것을 설정해주지 않으면 RecyclerView는 동작하지 않는다.

5. RecyclerView.Adapter를 상속받는 클래스를 생성한다.

public class RecycleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<RecycleItem> mItems;

    public RecycleAdapter(List<RecycleItem> listItems) {
        mItems = listItems;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View v = inflater.inflate(R.layout.custom_recycler_list_item, parent, false);
        return null;
    }

    @Override // View가 재사용될 때마다 호출된다.
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    }

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

컨트롤러 객체인 Adapter는 RecyclerView와 RecyclerView의 데이터 사이에 위치하여 모든 데이터를 관리한다.
List는 순차 리스트를 지원하는 인터페이스로, 지정된 타입(E)의 객체가 저장된다.
Adapter 인스턴스에 입력되는 List로 View 객체들의 정보를 입력한다.

onCreateViewHolder: 리스트의 각 항목을 이루는 XML(디자인) 적용.
리스트 항목으로 보여줄 View(XML)를 inflate하여 그 View의 객체를 참조한 ViewHolder를 생성한다.
아직 ViewHolder 클래스를 만들지 않아서 반환 값을 null로 두었다.
onBindViewHolder: 리스트의 각 항목에 들어갈 데이터 지정.
(RecyclerView.ViewHolder) holder를 통해 ViewHolder를 참조하여 참조된 객체에 데이터 정보를 넣는다.
이 메서드도 viewHolder를 생성 후 사용할 것이다.
getItemCount: 화면에 보여 줄 데이터의 개수를 반환한다.

6. RecyclerView.ViewHolder를 상속받는 내부 클래스를 생성한다.

    private class RecycleHolder extends RecyclerView.ViewHolder {
        private TextView itemCategory, itemName;

        public RecycleHolder(View itemView) {
            super(itemView);
            itemCategory = (TextView) itemView.findViewById(R.id.tv_item_category);
            itemName = (TextView) itemView.findViewById(R.id.tv_item_name);
        }
    }

ViewHolder는 리스트에서 하나의 항목에 해당하는 View를 보존한다.
Adapter의 onCreateViewHolder가 ViewHolder를 생성하면서 전달한 View를 itemView가 받아 그 View의 객체를 가져온다.
객체는 itemView.findViewById()를 통해 가져와서 참조한다.

7. RecyclerAdapter 에서 ViewHolder를 반환하고, 그것을 통해 리스트 항목에 데이터 정보를 넣도록 입력한다.

public class RecycleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    ...

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ...

        return new RecycleHolder(v);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        RecycleItem recyclerItem = mItems.get(position);
        RecycleHolder rHolder = (RecycleHolder) holder;
        rHolder.itemCategory.setText(recyclerItem.getCategory());
        rHolder.itemName.setText(recyclerItem.getName());
    }

    ...
}


8. RecyclerFragment로 되돌아가서 List 정보를 만들고 RecyclerView에 Adapter를 넣어준다.

public class RecyclerActivity extends AppCompatActivity {

    private RecycleAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...

        if(adapter == null){
            adapter = new RecycleAdapter(setList());
            mRecyclerView.setAdapter(adapter);
        }
    }

    public List<RecycleItem> setList(){
        List<RecycleItem> mRecycleItems = new ArrayList<>();
        for(int i=0; i<100; i++){
            RecycleItem recycleItem = new RecycleItem();
            recycleItem.setCategory("이름");
            recycleItem.setName("홍길동");
            mRecycleItems.add(recycleItem);
        }
        return mRecycleItems;
    }
}

item에 정보를 넣은 다음, list에 item을 넣으면 하나의 리스트 항목이 만들어진다.
그렇게 만들어진 리스트를 Adapter에 전달받아 ViewHolder를 통해 리스트를 그려준다.