RecyclerView , CardView 사용하기 :: 안드로이드 설치 및 개발[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

안드로이드 설치 및 개발
[1]
등록일:2018-08-21 10:24:48 (0%)
작성자:
제목:RecyclerView , CardView 사용하기

항상 ListView 로만 코딩을 해오다가,


ListView보다 성능과 퍼포먼스가 더 좋다고 하는 RecyclerView, CardView를 사용해보려 한다.


android developer의 training에 올라온 게시글로 사용법을 익혀보자.



The RecyclerView widget is a more advanced and flexible version of ListView

This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. 

Use the RecyclerViewwidget when you have data collections whose elements change at runtime based on user action or network events.



어렵지 않은 내용이다. 요약하자면 Listview 보다 성능적으로 좋고, RecyclerView는 최소한의 View 만으로도 큰 데이터를 효율적으로 스크롤링 해준다


또한, 사용자의 입장에서 시시각각 데이터가 변화할때(사용자의 액션을 처리하거나, 네트워크 처리등) 사용하기를 권장한다고 적혀있다.



The RecyclerView class simplifies the display and handling of large data sets by providing:

  • Layout managers for positioning items
  • Default animations for common item operations, such as removal or addition of items

You also have the flexibility to define custom layout managers and animations for RecyclerView widgets.



요약하자면, RecyclerView는 기본적으로 LayoutManager를 사용하여 item을 관리하고, 


사용자입장에서 item의 변화(삭제 되거나 추가등)를 느낄 수 있도록, 기본 애니메이션이 있다고 한다. 


또한, LayoutManager를 사용하여 효과적으로 item의 정렬 과 애니메이션등을 다룰 수 있다고 한다.


중요한것은,  Adapter를 통해 data를 RecyclerView에 연결시킨다. 

(RecyclerView는 데이터를 사용자에게 어떻게 보여줄지 그림담당만 한다.)


RecyclerView에 대한 설명은 이정도로 충분하다. (더 자세한 설명을 알고 싶다면, http://developer.android.com/training/material/lists-cards.html 을 참고)


이번엔 CardView에 대해 간단히 설명 하자면, 


Card모양의 View이다. 즉, 예전에는 custom 하여 card모양을 흉내냈지만, CardView가 나옴으로써 좀더 쉽게 card를 표현 할 수 있다.


(material 디자인에 맞게, 그림자와 클릭 효과등을 지정 할 수 있다.) 이러한 view를 RecyclerView와 함께 사용할 것이다. 


좀더 세부적으로 설명하자면, 


ListView 에는 각각 item들이 차지하는 view 의 공간이 있다. 이 공간을 사용자 입맛에 맞게 커스텀하여 데이터를 표현하는 것이다.


RecyclerView에서는 위와 같은 공간을 CardView로 붙일 것이다.



 

이제 직접 코딩을 해보자. 생각보다 간단하다.


먼저, 해당 위젯을 쓰기 위해서는 라이브러리가 필요하다. (안드로이드 스튜디오 기준.)



dependencies {
   
...
    compile
'com.android.support:cardview-v7:21.0.+'
    compile
'com.android.support:recyclerview-v7:21.0.+'
}



해당 프로젝트 graddle에 추가한다. 그 다음으로, layout 폴더에  my_activity를 만들고 아래와 같이 작성한다.


<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
   
android:id="@+id/my_recycler_view"
   
android:scrollbars="vertical"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"/>



위에서 설명했듯이, RecyclerView에는 LayoutManager가 필요하다. 아래의 코딩을 보자.(MyActivity.java)


public class MyActivity extends Activity {
   
private RecyclerView mRecyclerView;
   
private RecyclerView.Adapter mAdapter;
   
private RecyclerView.LayoutManager mLayoutManager;

   
@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)
        mAdapter
= new MyAdapter(myDataset);
        mRecyclerView
.setAdapter(mAdapter);
   
}
   
...
}



어렵지 않다. 위에서 설명한데로 RecyclerView의 객체인 mRecyclerView를 선언한후,


item정렬을 위한 LayoutManager를 LinearLayoutManager로 사용한다.(Linear 이므로 아이템이 수직,수평으로 배치 될 것이다.)


데이터와 RecyclerView를 연결 시키기 위한 adpaer로 MyAdapter를 선언하였다. 


이러한 LayoutManager와 Adapter를 setLayoutManager 와 setAdapter 메서드로 셋팅한다.


여기까지 했다면, MyAdapter에 빨간줄이 들어올 것이다.(아직 선언 하지 않았으니까....)


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  에서 받을 수 있다.



출처: http://mommoo.tistory.com/2?category=577449 [개발자로 홀로 서기]


[본문링크] RecyclerView , CardView 사용하기
[1]
코멘트(이글의 트랙백 주소:/cafe/tb_receive.php?no=34798
작성자
비밀번호

 

SSISOCommunity

[이전]

Copyright byCopyright ⓒ2005, SSISO Community All Rights Reserved.