Github에 Android 와 관련된 샘플을 업로드할 예정이다.
시리즈 중 1편으로 RecyclerView 와 CardView를 활용한 간단한 리스트 화면을 만들어 봤다.
(https://github.com/kajsss/android-example)
Layout 작성
레이아웃은 RecyclerVIew를 포함하고 있는 메인 페이지와 각 아이템을 그리는 카드뷰 레이아웃 2개가 필요하다.
<activity_main> 에서는 적당한 위치에 RecyclerVeiw 를 위치 시켰다.
<?xml version="1.0" encoding="utf-8"?>
<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.miloapp.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</RelativeLayout>
</LinearLayout>
<item_cardview> 에서는 RecyclerView 안에 그려질 아이템의 레이아웃을 설정한다. 예제에서는 Title과 Description 두개의 TextView로 구성된다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
card_view:cardCornerRadius="4dp"
card_view:cardBackgroundColor="@color/colorPrimary"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:textStyle="bold"
android:textSize="36sp"
tools:text="M"/>
<TextView
android:id="@+id/text_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="15sp"
android:text="I"
android:layout_centerInParent="true"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
코드 작성
public class MainActivity extends AppCompatActivity {
@BindView(R.id.recycler_view)
RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
ItemRepository itemRepository = new ItemRepository();
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(getApplicationContext(), itemRepository.getAllItems());
mRecyclerView.setAdapter(recyclerViewAdapter);
}
}
Main Activity에서는 RecyclerView를 Binding 하고 RecyclerView 에 LayoutManager 와 Adapter를 셋팅해주는 코드가 필요하다.
RecyclerViewAdapter 에는 화면에 그려줄 ObjectList 를 같이 넘겨줘서 화면에 그리도록 한다.
위 코드에서 itemRepository 에서는 List<Item> 타입을 리턴하게 된다.
@Data
@AllArgsConstructor
public class Item {
String title;
String description;
}
VO 클래스는 lombok annotaiton 을 이용하여 Setter나 Getter를 자동으로 생성하도록 하였다.
public class ItemRepository {
public List<Item> getAllItems(){
return dummyData();
}
private List<Item> dummyData(){
List<Item> dummyList = new ArrayList<>();
dummyList.add(new Item("A","apple"));
dummyList.add(new Item("B","Baggin"));
dummyList.add(new Item("C","Cati"));
dummyList.add(new Item("D","Dadday"));
return dummyList;
}
}
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolders> {
List<Item> itemList;
private Context context;
public RecyclerViewAdapter(Context context, List<Item> itemList) {
this.itemList = itemList;
this.context = context;
}
@Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layout = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cardview, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layout);
return rcv;
}
@Override
public void onBindViewHolder(RecyclerViewHolders holder, int position) {
holder.title.setText(itemList.get(position).getTitle());
holder.description.setText(itemList.get(position).getDescription());
}
@Override
public int getItemCount() {
return this.itemList.size();
}
class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView title;
TextView description;
public RecyclerViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
title = (TextView) itemView.findViewById(R.id.text_title);
description = (TextView) itemView.findViewById(R.id.text_description);
}
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), ((TextView) view.findViewById(R.id.text_title)).getText() + "Item Clicked", Toast.LENGTH_SHORT).show();
}
}
}
가장 중요한 부분인 RecyclerViewAdapter 부분이다. 전체 소스는 위와 같고 아래에서 좀 더 자세히 설명 하도록 하겠다.
RecyclerView Adapter를 상속 받으면 onCreateViewHolder, onBindViewHolder, getItemCount 를 재정의(Override) 해야 한다.
public RecyclerViewAdapter(Context context, List<Item> itemList) {
this.itemList = itemList;
this.context = context;}
RecyclerView Adapter의 역할은 RecyclerView에 데이터를 그려주는 역할을 담당한다. 그 역할을 위해서 그릴 대상인 ItemList 를 파라미터로 전달 받았다.
@Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layout = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cardview, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layout);
return rcv;
}
onCreateViewHolder는 데이터를 담을 뷰 홀더를 생성하여 리턴한다. 이때 위에서만들었던 카드뷰 Layout을 inflate 한다.
class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView title;
TextView description;
public RecyclerViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
title = (TextView) itemView.findViewById(R.id.text_title);
description = (TextView) itemView.findViewById(R.id.text_description);
}
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), ((TextView) view.findViewById(R.id.text_title)).getText() + "Item Clicked", Toast.LENGTH_SHORT).show();
}
}
뷰홀더는 Layout에 있는 Component와 Adapter 를 연결하기 위한 클래스라고 보면 이해가 쉬울 거 같다.
뷰홀더에서 각 아이템을 클릭 했을때 Action을 구현하였다.
@Override
public void onBindViewHolder(RecyclerViewHolders holder, int position) {
holder.title.setText(itemList.get(position).getTitle());
holder.description.setText(itemList.get(position).getDescription());
}
onBindViewHolder에서는 전달받은 아이템을 홀더에 값을 셋팅해주는 역할을 수행하게된다.
이때 홀더를 이용하여 값을 셋팅하면 리스트에 보여지게 된다.
@Override
public int getItemCount() {
return this.itemList.size();
}
전체 아이템 갯수를 리턴하도록 한다.
------ 끝 -----
'Programming' 카테고리의 다른 글
Java8 Lambda 최대값 갯수 표현식 (0) | 2017.06.04 |
---|---|
[JavaScript] Switch - Fall Through (0) | 2017.05.28 |
Android TestCase 빌드시 메모리 문제 (Robolectric) (0) | 2017.04.26 |
안드로이드 MVC, MVP Pattern (0) | 2017.04.05 |
Android Clean Architecture (0) | 2017.04.03 |