http://mommoo.tistory.com/1 ( RecyclerView , CardView 사용하기.(1) )




2편이다. 처음 읽는 독자는 위의 경로의 포스팅을 먼저 읽기를 권한다.


RecyclerView에 필요한 Adpater를 선언할 것이다.

참조한 구글 문서는 단순히 TextView만을 이용한 예제이다.


본 게시물은 추가적으로 image를 넣어 image와 text로 구성된 예제임을 밝힌다.



MyAdapter.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private ArrayList<MyData> 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 ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case 
        public ImageView mImageView;
        public TextView mTextView;
 
        public ViewHolder(View view) {
            super(view);
            mImageView = (ImageView)view.findViewById(R.id.image);
            mTextView = (TextView)view.findViewById(R.id.textview);
        }
    }
 
    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(ArrayList<MyData> myDataset) {
        mDataset = myDataset;
    }
 
    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                               .inflate(R.layout.my_view, parent, false);
        // set the view's size, margins, paddings and layout parameters
        ...
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }
 
    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.mTextView.setText(mDataset.get(position).text);
        holder.mImageView.setImageResource(mDataset.get(position).img);
    }
 
    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.size();
    }
}
 
class MyData{
    public String text;
    public int img;
    public MyData(String text, int img){
        this.text = text;
        this.img = img;
    }
}
cs



MyAdpater.class를 선언하고, RecyclerView.Adapter를 상속 받았다.


MyAdpater안에 직접 구현한 ViewHolder 클래스를 제네릭으로 받는 구조이다.  물론 직접 만드는 ViewHolder도 


ReclerView.ViewHolder를 상속받아야 한다.


(ViewHolder는 ListView를 사용할 당시, RecylerView처럼 View를 효율적으로 쓰기 위한 디자인 패턴중 하나였다. 

리소스를 제법 잡어먹는 findViewById()를 적게 호출하기 위함이다. RecyclerView 에서는 적극적으로 ViewHolder 패턴을 사용하라고 권장한다. )


ViewHolder 클래스는 RecyclerView의 item에 들어갈 view를 받은후 그 view 안에 있는 ImageView와 TextView를 초기화 한다.


그다음은 MyAdapter 생성자가 보이는데, 매개변수로 ArrayList<MyData> 객체를 받는다. MyData 클래스는 data-set을 위한 클래스로


해당 예제에 맨 아래에 생성했다.




중요한 내용은 지금부터이다.


onCreateViewHolder 메서드안의 내용을 잘 바꾸어야 내가 원하는 결과물이 나온다.


첫번째로, View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_view, parent, false); 는


앞서 말한 ViewHolder에 넣어줄 view를 찾는 과정이다. my_view라는 xml에는 cardview가 들어갈 예정이다.


이 view를 넣기위한 ViewHolder를 다음과 같이 선언한 후 넣는다.


 ViewHolder vh = new ViewHolder(v);


그다음 onBindViewHolder 메서드를 보자. 이 메서드는 RecyclerView의 item의 셋팅과 사용자가 스크롤링 할때, 호출되는 메서드이다.


우리가 원하는 데이터가 포지션별로 ArrayList<MyData>에 저장되어 있다. 이러한 데이터를 포지션별로 보여주는 것을 보장해준다.


마지막으로 MyData 클래스이다. 우리가 원하는 image와 text 데이터를 보관하기 위한 데이터 저장소 개념으로 보면 된다.



다음은 위에서 소개한 my_view.xml을 코딩 해보자.



my_view.xml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.CardView
        android:id="@+id/cardview"
        card:cardCornerRadius="3dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
        <ImageView
            android:scaleType="fitXY"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:id="@+id/image"/>
        <TextView
            android:id="@+id/textview"
            android:gravity="center|left"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"/>
        </LinearLayout>
    </android.support.v7.widget.CardView>
</RelativeLayout>
cs



위의 CardView 위젯을 보면 android: 대신 card: 인자가 보이는데, 


이 인자는 부모뷰에 xmlns:card="http://schemas.android.com/apk/res-auto"


등록을 해주면 된다. cardCornerRadius 값은 모서리 둥근 정도를 결정한다.


해당 카드뷰 view 아래는 데이터를 보여줄(image,text) 하위 view들을 지정했다.


cardview 자체는 FrameLayout를 상속 받기 때문에 따로 LinearLayout을 선언하여 수직 정렬 하였다.


다 끝났다. 이제 MyActivity로 돌아가 데이터를 넣어본다.



MyActivity.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class MyActivity extends Activity {
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private ArrayList<MyData> myDataset;    
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        mRecyclerView = (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
        mRecyclerView.setHasFixedSize(true);
 
        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
 
        // specify an adapter (see also next example)
        myDataset = new ArrayList<>();
        mAdapter = new MyAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
        
        myDataset.add(new MyData("#InsideOut", R.mipmap.insideout));
        myDataset.add(new MyData("#Mini", R.mipmap.mini));
        myDataset.add(new MyData("#ToyStroy", R.mipmap.toystory));
 
    }
    ...
}
cs


컴파일을 해보면...




멋진 카드효과와 함께 잘 나온다.


해당 프로젝트는 https://github.com/Mommoo/ExampleCode/tree/master/RecyclerView  에서 받을 수 있다.




포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

+ Recent posts