본문 바로가기

PHP/Android

RecyclerView 만들기

반응형

안드로이드 앱을 만들게 되면 99%는 RecyclerView를 만들게 됩니다.

처음 접하는 분은 엄청 복잡합니다.

정리를 해보겠습니다.

 

참고: https://developer.android.com/guide/topics/ui/layout/recyclerview#java

 

직접 제작

 

 

1. RecyclerView object가 있습니다. 이 object 안에 layout을 넣습니다.

2. layout은 layout manager를 통해서 채워지게 됩니다.

3. layout manager는 LinearLayoutManager 또는 GridLayoutManager가 있습니다.

4. 리스트 안에 있는 각 view는 각 view holder object가 담당을 합니다.

5. 이 objects는 extending한 RecyclerView.ViewHolder입니다.

6. 각 object는 각각의 item을 담당합니다.

7. 예를 들어서 music collection이 있다면 각 view holder는 각 앨범을 담당합니다.

8. RecyclerView는 view holders를 화면에 보여지는 만큼 그리고 extra로 조금 더 생성합니다.

9. 화면을 스크롤하면 보이지 않는 views를 이용해서 데이터를 집어넣는 겁니다. (재활용)

 

 

10. view holder objects는 adapter가 담당을 합니다.

11. RecyclerView.Adapter를 extends해서 만드는 겁니다.

구현해야 할 메소드

- onCreateViewHolder(): view holder를 생성

- onBindViewHolder(): 데이터를 view holder에 bind

- getItemCount(): item이 몇 개인지 파악해서 리스트에 넣을 data 숫자

 

12. adapter가 view holders를 생성하는 겁니다.

13. adapter가 데이터를 view holders에 bind하는 겁니다.

14. view holders마다 순서(position)를 주고 adapter의 onBindViewHolder() 메소드를 이용해서 호출하는 겁니다.

 

15. RecycleView가 view holders를 10개(position 0 - 9) 만들었다고 치면 extra로 1개를 더 만듭니다. 스크롤해서 내리더라도 이미 extra로 1개가 준비되어 있어서 성능저하가 덜 합니다. 그리고 view holders를 더 생성하는 겁니다.

 

16. 만약 보여준 데이터(items)이 도중에 변경이 되었다면 RecyclerView.Adapter.notify…() 메소드를 이용해서 adapter에 알려줄 수 있습니다. 그럼 변경된 데이터만 업데이트 시킬 수 있습니다.

 

 

코딩 시작!

 

1. Add the support library

build.gradle를 오픈합니다.

그리고 dependencies section에 아래와 같이 삽입합니다.

dependencies {
    implementation 'com.android.support:recyclerview-v7:28.0.0'
}

 

2. Add RecyclerView to your layout

RecyclerView를 사용할 layout에 아래 widget 코드를 넣습니다.

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

 

추가로 item layout을 만들어야 합니다.

새로 xml 파일을 만들면 됩니다.

예: row_item.xml

리스트로 보여줄 template입니다.

한 row만 디자인하면 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp"
    android:gravity="center_vertical"
    android:layout_marginBottom="8dp"
    android:background="@android:color/white">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical"
        android:gravity="center_vertical">

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:text="TITLE"
            android:textSize="15sp"
            android:textColor="@android:color/black"
            android:textStyle="bold"/>

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:text="content"
            android:textSize="13sp"
            android:textColor="@android:color/darker_gray"/>
    </LinearLayout>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@mipmap/ic_launcher"/>
</LinearLayout>

 

 

그리고 아래와 같이 합니다.

 

1. RecyclerView widget을 object로 준비해둡니다.

2. object를 layout manager를 생성해서 연결시킵니다.

3. data를 첨부할 adapter를 만들어서 연결시킵니다. 

public class MyActivity extends Activity {
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        recyclerView.setHasFixedSize(true);

        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        recyclerView.setAdapter(mAdapter);
    }
    // ...
}

 

3. Add a list adapter

a. 데이터를 list로 보여주려면 RecyclerView.Adapter class를 extends해야 합니다.

b. 이 object는 views의 items을 생성합니다.

c. 그리고 스크롤해서 보이지 않는 view holder의 데이터를 새로운 데이터로 교체를 해주기도 합니다. r

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private String[] mDataset;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView textView;
        public MyViewHolder(TextView v) {
            super(v);
            textView = v;
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        TextView v = (TextView) LayoutInflater.from(parent.getContext())
                .inflate(R.layout.my_text_view, parent, false);
        ...
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.textView.setText(mDataset[position]);

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

a. layout manager가 adapter의 onCreateViewHolder() 메소드를 호출합니다.

b. 이 메소드는 RecyclerView.ViewHolder를 construct해야 하고 view로 디스플레이할 내용을 설정합니다.

c. ViewHolder의 type이 adapter class에서 정의한 type과 꼭 동일해야 합니다.

d. 보통 XML layout 파일을 inflating해서 세팅합니다.

e. 이렇게 하는 이유는 view holder가 아직 data랑 연결이 되어 있지 않기 때문입니다.

f. 또한 이 메소드는 view의 내용을 세팅하지도 않습니다.

 

g. adapter의 onBindViewHolder() 메소드를 호출해서 layout manager가 데이터를 bind합니다.

h. 그리고 RecyclerView에 view holder의 position을 전달해줍니다.

i. onBindViewHolder() 메소드는 데이터를 불러와서 view holder's layout에 채워져야 합니다.

예: RecyclerView에 이름을 리스트로 보여준다고 하면 onBindViewHolder() 메소스가 이름 데이터를 불러와서 view holder의 TextView 위젯에 채워넣는다.

 

j. 리스트를 업데이트해야 하는 경우 RecyclerView.Adapter object에 있는 notification method인 notifyItemChanged() 메소드를 호출할 수 있습니다. 그럼 layout manager가 해당하는 view holder를 다시 bind를 합니다.

 

 

 

 

 

 

 

 

 

반응형