Abstract.
안드로이드 개발을 진행하면서 카드뷰(CardView) 또는 리사이클러뷰(RecyclerView)를 사용할 때, 사용되는 아이템의 배경색을 각각 개별로 설정하고 싶어졌다. 보통은 카드뷰나 리사이클러뷰를 사용하면 하나의 아이템 레이아웃을 이용하여 액티비티 레이아웃에 연결하여 구현하고는 하는데, 일반적으로 아이템의 배경색은 한가지로만 설정이 된다.
xml 레이아웃 파일 작성
먼저 레이아웃 파일을 만들어보자. 본 포스팅에서는 메인 액티비티를 DashboardActivity로 명명하도록 하겠다. 만들어야 할 레이아웃 파일은 이에 따라 activity_dashboard.xml과 item_dashboard.xml이 되겠다. 기본적으로 데이터바인딩을 사용하기로 한다. 해당 코드는 기존에 개인적으로 사용하던 코드를 재활용하였으므로 불필요한 코드가 일부 들어가있을 수 있다.
1. activity_dashboard.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:id="@+id/nsv_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/grey1"
android:paddingBottom="4dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.drawerlayout.widget.DrawerLayout>
</layout>
activity_dashboard.xml에서는 카드뷰를 연결하기 위해 RecyclerView를 사용하였다. 여기에 item_dashboard.xml 파일을 연결하게 된다.
2. item_dashboard.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:clickable="true"
android:focusable="true"
app:cardCornerRadius="5dp"
app:cardElevation="4dp">
<LinearLayout
android:id="@+id/rl_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_card_selector_blue"
android:orientation="horizontal" >
<ImageView
android:id="@+id/iv_icon"
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:src="@drawable/ic_item1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_vertical"
android:paddingStart="24dp"
android:paddingTop="18dp"
android:paddingEnd="24dp"
android:paddingBottom="18dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="@string/title_item1"
android:textStyle="bold"
android:textColor="@color/navy8"
android:textSize="17.3sp" />
<TextView
android:id="@+id/tv_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:lineSpacingExtra="5.7dp"
android:paddingTop="11dp"
android:text="@string/description_item1"
android:textColor="@color/black"
android:textSize="13.3sp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</layout>
item_dashboard.xml의 화면 구성은 크게 ic_item(이미지파일), title_item(아이템 타이틀), description_item(아이템 설명)의 3가지로 구성된다. 각각의 구성요소는 개인 취향에 맞게 커스텀하면 된다.
drawable 파일 작성
먼저 각각의 카드뷰에 적용될 카드셀렉터(card_selector) 레이아웃 파일을 만들어보도록 한다.
1. color.xml
<resources>
<drawable name="default_blue">@color/blue0</drawable>
<drawable name="pressed_blue">@color/blue2</drawable>
<drawable name="default_green">@color/green0</drawable>
<drawable name="pressed_green">@color/green2</drawable>
<drawable name="default_red">@color/red0</drawable>
<drawable name="pressed_red">@color/red2</drawable>
<drawable name="default_yellow">@color/yellow0</drawable>
<drawable name="pressed_yellow">@color/yellow2</drawable>
<drawable name="default_orange">@color/orange0</drawable>
<drawable name="pressed_orange">@color/orange2</drawable>
<drawable name="white">@android:color/white</drawable>
</resources>
가장 먼저 color.xml 파일에 카드뷰를 눌렀을 때의 색상들을 지정해준다.
2. bg_card_selector_blue.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/pressed_blue" android:state_pressed="true" />
<item android:drawable="@drawable/default_blue" />
</selector>
카드 셀렉터를 생성하고 각각의 아이템별로 셀렉터 효과를 지정하기 위해 color.xml 파일에서 정의한 drawable 리소스를 연결해준다. bg_card_selector_green.xml과 bg_card_selector_red.xml 파일에도 동일하게 각각 해당하는 drawable 리소스를 적용한다.
3. bg_card_selector_green.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/pressed_green" android:state_pressed="true" />
<item android:drawable="@drawable/default_green" />
</selector>
4. bg_card_selector_red.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/pressed_red" android:state_pressed="true" />
<item android:drawable="@drawable/default_red" />
</selector>
java 코드 작성
카드뷰를 구현하기 위해서는 몇 가지 구성요소가 필요하다. 연결하고자 하는 Data, 화면에 카드뷰 연결을 위한 Adapter, 어댑터에 Data를 연결하기 위한 ViewHolder와 Helper클래스를 작성해야한다. 각각의 자바 클래스의 코드를 작성해보자.
1. DashboardData.java
package com.minsuuuus.cardviewtest;
public class DashboardData {
public enum DashboardItemType {
ITEM_TYPE1(0),
ITEM_TYPE2(1),
ITEM_TYPE3(2);
private int value;
DashboardItemType(int value) {
this.value = value;
}
}
public static class DashboardItem {
public DashboardItemType type;
public int position;
public DashboardItem(DashboardItemType type, int position) {
this.type = type;
this.position = position;
}
}
}
DashboardData.java는 대시보드에 연결하고자 하는 아이템(DashboardItem, DashboardItemType)을 정의한 코드다.
2. DashboardListOrderingHelper.java
package com.minsuuuus.cardviewtest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.minsuuuus.cardviewtest.DashboardData.DashboardItem;
import com.minsuuuus.cardviewtest.DashboardData.DashboardItemType;
public class DashboardListOrderingHelper {
public List<DashboardItem> items = new ArrayList<>();
public DashboardListOrderingHelper() {
setDefaultOrder();
}
private void setDefaultOrder() {
items.clear();
DashboardItem[] defaultOrder;
defaultOrder = new DashboardItem[] {
new DashboardItem(DashboardItemType.ITEM_TYPE1, 0),
new DashboardItem(DashboardItemType.ITEM_TYPE2, 1),
new DashboardItem(DashboardItemType.ITEM_TYPE3, 2),
};
items.addAll(Arrays.asList(defaultOrder));
}
private void setItemPosition() {
for (int i = 0; i < items.size(); i++) {
items.get(i).position = i;
}
}
public DashboardItem getItem(DashboardItemType type) {
for (int i = 0; i < items.size(); i++) {
DashboardItem item = items.get(i);
if (type == item.type) {
item.position = i;
return item;
}
}
return null;
}
public void setItem(DashboardItem item) {
items.set(item.position, item);
}
}
DashboardListOrderingHelper.java 의 코드는 DashboardData.java에서 정의된 대시보드 아이템을 불러와서 연결되는 갯수 및 순서를 셋팅해주는 역할을 한다.
3. DashboardViewHolder.java
package com.minsuuuus.cardviewtest;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.minsuuuus.cardviewtest.DashboardData.DashboardItem;
import com.minsuuuus.cardviewtest.DashboardData.DashboardItemType;
public class DashboardViewHolder extends RecyclerView.ViewHolder {
CardView cvItem;
View root;
ImageView ivIcon;
TextView tvTitle, tvDescription;
Context context;
private DashboardItemType mItemType;
public DashboardViewHolder(@NonNull View itemView) {
super(itemView);
cvItem = itemView.findViewById(R.id.item);
root = itemView.findViewById(R.id.rl_root);
ivIcon = itemView.findViewById(R.id.iv_icon);
tvTitle = itemView.findViewById(R.id.tv_title);
tvDescription = itemView.findViewById(R.id.tv_description);
}
public void bindData(DashboardItem item) {
setItemType(item.type, item);
}
private void setItemType(DashboardItemType itemType, DashboardItem item) {
mItemType = itemType;
switch (itemType) {
case ITEM_TYPE1:
setItem1(item);
break;
case ITEM_TYPE2:
setItem2(item);
break;
case ITEM_TYPE3:
setItem3(item);
break;
}
}
private void setItem1(DashboardItem item) {
root.setBackground(ResourcesCompat.getDrawable(root.getResources(), R.drawable.bg_card_selector_blue, null)); // 카드셀렉터 개별 설정
ivIcon.setImageResource(R.drawable.ic_item1);
ivIcon.setColorFilter(Color.parseColor("#4C89FF"));
tvTitle.setText(R.string.title_item1);
tvDescription.setText(R.string.description_item1);
}
private void setItem2(DashboardItem item) {
root.setBackground(ResourcesCompat.getDrawable(root.getResources(), R.drawable.bg_card_selector_green, null)); // 카드셀렉터 개별 설정
ivIcon.setImageResource(R.drawable.ic_item2);
ivIcon.setColorFilter(Color.parseColor("#48C83F"));
tvTitle.setText(R.string.title_item2);
tvDescription.setText(R.string.description_item2);
}
private void setItem3(DashboardItem item) {
root.setBackground(ResourcesCompat.getDrawable(root.getResources(), R.drawable.bg_card_selector_red, null)); // 카드셀렉터 개별 설정
ivIcon.setImageResource(R.drawable.ic_item3);
ivIcon.setColorFilter(Color.parseColor("#FF5454"));
tvTitle.setText(R.string.title_item3);
tvDescription.setText(R.string.description_item3);
}
}
DashboardViewHolder.java 코드는 대시보드에 연결되는 각 아이템의 세부적인 구성요소(아이콘, 텍스트, 배경색 등)를 셋팅해주는 역할을 한다. 앞서 작성한 drawable 파일의 리소스를 불러와 연결한다.
4. DashboardAdapter.java
package com.minsuuuus.cardviewtest;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.minsuuuus.cardviewtest.DashboardData.DashboardItem;
public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final DashboardListOrderingHelper mListOrderingHelper;
private final OnRecyclerItemClickListener mListener;
private final Context mContext;
public DashboardAdapter(@Nullable Context context, @Nullable OnRecyclerItemClickListener listener) {
mContext = context;
mListOrderingHelper = new DashboardListOrderingHelper();
mListener = listener;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
switch (viewType) {
default:
View contentView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_dashboard, parent, false);
return new DashboardViewHolder(contentView);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
DashboardItem dashboardItem = mListOrderingHelper.items.get(position);
DashboardViewHolder dashboardViewHolder = new DashboardViewHolder(holder.itemView);
dashboardViewHolder.bindData(dashboardItem);
// 대시보드 아이템 클릭 시 동작
holder.itemView.setOnClickListener(v -> {
if (mListener != null) mListener.onItemClick(dashboardItem);
});
}
@Override
public int getItemCount() {
return mListOrderingHelper.items.size();
}
public interface OnRecyclerItemClickListener {
void onItemClick(DashboardItem dashboardItem);
}
}
DashboardAdapter.java의 코드는 DashboardActivity.java 파일에 연결되는 뷰홀더를 생성해주고 연결해준다. 또한, 대시보드의 아이템을 클릭할 때의 동작을 정의한다.
5. DashboardActivity.java
package com.minsuuuus.cardviewtest;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import com.minsuuuus.cardviewtest.databinding.ActivityDashboardBinding;
import com.minsuuuus.cardviewtest.DashboardData.DashboardItem;
public class DashboardActivity extends AppCompatActivity implements DashboardAdapter.OnRecyclerItemClickListener {
DashboardAdapter mAdapter;
ActivityDashboardBinding binding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_dashboard);
mAdapter = new DashboardAdapter(this, this);
binding.rvContent.setAdapter(mAdapter); // 카드뷰 item 연결
}
@Override
public void onItemClick(DashboardItem dashboardItem) {
}
}
DashboardActivity.java의 코드에서는 DashboardAdapter를 연결해주고, 각각의 아이템에 대한 데이터와 동작들을 구성하는 역할을 한다. 본 포스팅에서는 카드뷰의 각각의 아이템에 개별적으로 적용되는 배경색 및 아이콘 색을 확인하기 위한 포스팅이므로 동작에 대한 코드는 제외하였다.
실행 결과
작성된 코드를 빌드하여 실행하면 다음과 같은 결과를 확인할 수 있다. 카드뷰의 각 아이템 별로 서로 다른 아이콘과 배경색이 적용된 것을 확인할 수 있다. 이렇게 drawable 파일만 추가하여 카드뷰 아이템 별로 개별적인 디자인을 셋팅할 수 있다.
'Android > Android Lab' 카테고리의 다른 글
안드로이드 스튜디오 깃허브 연동 (1) | 2023.10.15 |
---|---|
안드로이드 권한 체크 구현(Permission Check) (1) | 2023.09.19 |
안드로이드 커스텀 체크박스 구현 (0) | 2023.03.10 |
안드로이드 DataBinding (1) | 2023.03.10 |
[Java] 안드로이드 간단한 설문조사 기능 구현 (0) | 2023.01.28 |
댓글