일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 라즈베리파이
- Machine Learning
- sw
- Raspberry
- keras
- 머신러닝
- 영상분석
- php
- 데이터
- Linux
- 고급C
- MySQL
- 서버
- 안드로이드
- Android
- FLASK
- Object Detection
- 디버그모드
- Deep Learning
- tensorflow
- RapidCheck
- tracking
- 지능형
- detection
- Python
- C언어
- 가상환경
- Video
- 정리
- IMAGE
- Today
- Total
건프의 소소한 개발이야기
[안드로이드] Android RecyclerView with CardView 본문
안녕하세요, 건프입니다.
이번에는 Android Programming 에서 가장 논란이 많았던 리스트뷰(ListView) 의 대체용으로 발표된 RecyclerView 를 다뤄보겠습니다.
RecyclerView 에서는 예전 ListView 를 제작할 때, 리소스 낭비를 줄이기 위한 Holder 패턴(Pattern) 을, 강제사항으로 만들어두고,
Interface 함수들을 좀 더 목적에 부합하도록 만들어 진 뷰입니다.
1. 어뎁터(Adapter)는 다음과 같습니다.
public class StoreSearchAdapter extends RecyclerView.Adapter<StoreSearchAdapter.ViewHolder> {
Context context;
List<StoreInfo> items;
int item_layout;
public StoreSearchAdapter(Context context, List<StoreInfo> items, int item_layout){
this.context = context;
this.items = items;
this.item_layout = item_layout;
}
@Override
public StoreSearchAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if (viewType == 0) {
View v = inflater.inflate(R.layout.search_store_item_front, null);
return new FrontCardHolder(v);
}else{
View v = inflater.inflate(R.layout.search_store_item_back, parent, false);
return new BackCardHolder(v);
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
StoreInfo item = items.get(position);
Log.d("holder.getItemType", holder.getItemViewType()+"");
switch (holder.getItemViewType()){
case 0:
FrontCardHolder fHolder = (FrontCardHolder)holder;
Drawable drawable = context.getResources().getDrawable(item.getImage());
fHolder.image.setBackground(drawable);
// fHolder.card.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// Toast.makeText(context, "position : "+position, Toast.LENGTH_SHORT).show();
// }
// });
fHolder.text.setText(item.getStoreName());
break;
case 1:
BackCardHolder bHolder = (BackCardHolder)holder;
bHolder.text.setText(item.getStoreName());
break;
}
}
@Override
public int getItemCount() {
return this.items.size();
}
@Override
public int getItemViewType(int position) {
return items.get(position).getFlipType();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int position = getPosition();
Toast.makeText(context, "holder position : "+position, Toast.LENGTH_SHORT).show();
items.get(position).flipCard();
notifyItemChanged(position);
}
}
public class FrontCardHolder extends ViewHolder{
public ImageView image;
public TextView text;
public CardView card;
public FrontCardHolder(View itemView) {
super(itemView);
image=(ImageView)itemView.findViewById(R.id.item_image_front);
text=(TextView)itemView.findViewById(R.id.item_text_front);
card = (CardView)itemView.findViewById(R.id.card_view);
}
}
public class BackCardHolder extends ViewHolder{
public TextView text;
public BackCardHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(R.id.item_text_back);
}
}
}
RecyclerView.Adapter 를 사용하면, 두개의 콜백함수를 오버라이드 받아야 합니다.
onCreateViewHolder() 와
onBindViewHolder() 인데
이름과 내부에 들어간 코드를 해석해보면, 새로운 뷰를 생성하는 것은 onCreateViewHolder 에서 작업하고 Holder를 생성해주면
나중에 다시 보여줄때는 재활용해서(Recycle) onBindViewHolder 에서 내용물을 그리는 것을 알 수 있습니다.
위의 코드는 카드뷰(CardView) 이용할때, 카드의 앞면과 뒷면을 둘 다 작업하려고 만들어진 Adapter 입니다.
2. Build.gradle 의 dependency를 설정해줍니다.
compile 'com.android.support:recyclerview-v7:23.3.0'
compile 'com.android.support:cardview-v7:23.0.+'
버전정보의 약간의 차이는 있을 수 있습니다. 일단 제 프로젝트에서 위 와 같이 사용했을 때, 문제없이 사용하고 있습니다.
3. 각각의 Xml 입니다.
- search_store_item_front.xml ( 카드 앞면 레이아웃)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/card_view"
card_view:cardCornerRadius="3dp"
card_view:cardElevation="3dp"
android:layout_width="match_parent"
android:layout_height="270dp"
android:layout_margin="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="210dp"
android:id="@+id/item_image_front"/>
<TextView
android:id="@+id/item_text_front"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="ddd"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
- search_store_item_back.xml (카드 뒷면 레이아웃)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/card_view"
card_view:cardCornerRadius="3dp"
card_view:cardElevation="3dp"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_margin="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/item_text_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="ddd"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/search_store_down"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
4. 화면에서의 코드입니다.
public class SearchFragment extends Fragment {
private final String TAG = "SearchFragment";
private CoilApplication app;
public SearchFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
app = (CoilApplication) getActivity().getApplicationContext();
Log.d(TAG, ""+app.storeAll.getItemList().size());
// Inflate the layout for this fragment
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_search, container, false);
RecyclerView recyclerView = (RecyclerView)rootView.findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
List<StoreInfo> items = new ArrayList<>();
StoreInfo[] item=new StoreInfo[5];
item[0]=new StoreInfo(R.drawable.logo_sample1,"#1");
item[1]=new StoreInfo(R.drawable.logo_sample2,"#2");
item[2]=new StoreInfo(R.drawable.logo_sample3,"#3");
item[3]=new StoreInfo(R.drawable.logo_sample3,"#4");
item[4]=new StoreInfo(R.drawable.logo_sample3,"#5");
for(int i=0;i<5;i++) items.add(item[i]);
recyclerView.setAdapter(new StoreSearchAdapter(getActivity(), items, R.layout.fragment_search));
return rootView;
}
}
불필요한 변수선언은 안하셔도 됩니다. (개인적인 작업하면서 들어간 코드들입니다)
5. 위의 화면의 레이아웃 입니다.
- fragment_search.xml
<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:orientation="vertical"
tools:context="com.brianandroid.myzzung.coli.ui.SearchFragment">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"/>
</LinearLayout>
6. 결과 화면 입니다
카드뷰가 포함된 형태
카드뷰를 누르면 위와 같이 뒷면이 보입니다.
도움이 되었길 바랍니다 :)
' 개발 이야기 > 안드로이드 이야기' 카테고리의 다른 글
[안드로이드] Material Dialog 관련 라이브러리 사용법 (2) (0) | 2016.05.24 |
---|---|
[안드로이드] Android Volley 에서 리스너(Listener)에 인자 넘기기 (0) | 2016.05.17 |
[안드로이드] Navigation View Header View 관리하기 (4) | 2016.05.07 |
[안드로이드] Google Cloud Message(GCM) 적용시키기 - (2) (2) | 2016.05.07 |
[안드로이드] Google Cloud Message(GCM) 적용시키기 - (1) (0) | 2016.05.07 |