728x90
프래그먼트에 카드뷰(CardView)와 리사이클러뷰(RecyclerView)를 사용하여 리스트를 만들어 보겠습니다.
- build.gradle(Module :app) 파일에 카드뷰와 리사이클러뷰를 추가해 줍니다.
dependencies {
//리사이클러뷰
implementation 'androidx.recyclerview:recyclerview:1.1.0'
// 카드뷰
implementation "androidx.cardview:cardview:1.0.0"
}
- 프래그먼트 xml에 리사이클러뷰를 넣어줍니다.

- 아이템으로 넣을 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:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:id="@+id/cardView"
card_view:cardCornerRadius="1dp"
card_view:cardElevation="15dp"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#eee">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:background="#fff"
android:layout_marginBottom="1dp">
<!-- <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="1dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">-->
<TextView
android:id="@+id/tvCategoryCV"
android:layout_width="92dp"
android:layout_height="21dp"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="1dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="262dp"
android:shadowColor="#0B0A0A"
android:text="카테고리"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#050404"
android:textSize="10dp" />
<TextView
android:id="@+id/tvTitleCV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvCategoryCV"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="1dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:shadowColor="#0B0A0A"
android:text="제목"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#050404"
android:gravity="center_vertical"
android:textSize="17dp"
/>
<!--
</LinearLayout>
-->
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ddd">
<!--Contents-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:padding="16dp">
<TextView
android:id="@+id/tvContentsCV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginStart="1dp"
android:text="글 내용..."
android:textSize="16sp" />
</RelativeLayout>
<!--이부분이 이미지 들어가는 부분-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rl_image"
android:background="@color/white">
<!--
<ImageView
android:id="@+id/ivImageCV"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
/>-->
<!-- android:adjustViewBounds="true" 뷰 사이즈로 이미지를 키워줌, 그리고 이미지 비율을 유지하며 맞춤-->
<!-- android:maxHeight="600dp 는 adjustViewBounds 써야 유효하다. -->
<ImageView
android:id="@+id/ivImageCV"
android:foregroundGravity="right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="100dp"
android:maxWidth="100dp"
android:adjustViewBounds="true"
android:background="#00ff0000"
/>
</RelativeLayout>
<!--닉네임-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:paddingLeft="16dp">
<TextView
android:id="@+id/tvNickNameCV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginStart="1dp"
android:text="닉네임"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="13sp" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ddd">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#fff"
android:layout_marginBottom="1dp"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<ImageView
android:id="@+id/imageView3"
android:layout_width="28dp"
android:layout_height="27dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="1dp"
android:src="@drawable/eye_icon" />
<TextView
android:id="@+id/tvHitCV"
android:textAlignment="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_toRightOf="@+id/imageView3"
android:text="6"
android:textAppearance="?android:attr/textAppearanceSmall" />
<!-- <CheckBox
android:id="@+id/ckBoxContentsLike"
android:layout_width="28dp"
android:layout_height="27dp"
android:layout_toRightOf="@+id/tvHitCV"
android:layout_centerVertical="true"
android:layout_marginStart="15dp"
android:button="@drawable/chk_like"
android:background="@drawable/border_00ff0000"/>-->
<ImageButton
android:id="@+id/ibLike"
android:layout_width="28dp"
android:layout_height="27dp"
android:layout_toRightOf="@+id/tvHitCV"
android:layout_centerVertical="true"
android:layout_marginStart="15dp"
android:src ="@drawable/ic_baseline_thumb_up_off_alt_24"
android:background="@drawable/border_00ff0000"/>
<TextView
android:id="@+id/tvContents_like"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_toRightOf="@+id/ibLike"
android:gravity="center_vertical"
android:hint="좋아요"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageView
android:id="@+id/imageView4"
android:layout_width="28dp"
android:layout_height="27dp"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_toRightOf="@id/tvContents_like"
android:src="@drawable/comment_icon" />
<TextView
android:id="@+id/tvCommentCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_toRightOf="@+id/imageView4"
android:text="댓글수"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceSmall" />
<!--날짜-->
<TextView
android:id="@+id/tvDateCV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_gravity="end"
android:layout_marginTop="15dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="15dp"
android:text="Date"
android:textSize="13sp"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
- 리사이클러뷰 어댑터를 만들어 줍니다. 스틱코드에 코드를 저장해 놓고 사용하면 편합니다.

ada 까지만 입력해도 제 Post에 등록해 놓은 코드를 전체 불러와서 사용이 가능합니다.
https://stickode.com/detail.html?no=2208
스틱코드
stickode.com

스틱코드 사용해서 개발 편하게 하기 : https://stickode.com/mainlogin.html
STICKODE
stickode.com
package com.Recyclerview;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.Activity.ContentsActivity;
import com.Listener.OnPostListener;
import com.R;
import java.util.ArrayList;
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {
private final ArrayList<DataModel> dataModelArrayList;
private Context context;
private OnPostListener onPostListener;
String getContentsNum;
int pos;
private final String TAG = "myRecyclerViewAdapter";
// 생성자: 생성자에서 데이터 리스트 객체를 전달받음.
public MyRecyclerViewAdapter(ArrayList<DataModel> dataModelArrayList, Context context) {
this.dataModelArrayList = dataModelArrayList;
this.context = context;
// 어댑터에서 액티비티 액션을 가져올 때 context가 필요한데 어댑터에는 context가 없다.
// 선택한 액티비티에 대한 context를 가져올 때 필요하다.
}
// 뷰홀더
// 이 부분에서 super를 통해 상속을 받았다.
// 이 RecyclerView 에 뷰 holder 에서 상속을 받아서 거기에 아이템 값을 찾아와야 한다.
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tvTitleCV, tvDateCV, tvContentsCV, tvNickNameCV, tvHitCV, tvCommentCount, tvCategoryCV;
public ImageView ivImageCV;
public ImageButton ibLike;
// 뷰홀더
public MyViewHolder(View view) {
super(view);
this.ivImageCV = (ImageView) view.findViewById(R.id.ivImageCV);
this.tvCategoryCV = (TextView) view.findViewById(R.id.tvCategoryCV);
this.tvTitleCV = (TextView) view.findViewById(R.id.tvTitleCV);
this.tvContentsCV = (TextView) view.findViewById(R.id.tvContentsCV);
this.tvNickNameCV = (TextView) view.findViewById(R.id.tvNickNameCV);
this.tvHitCV = (TextView) view.findViewById(R.id.tvHitCV);
this.tvCommentCount = (TextView) view.findViewById(R.id.tvCommentCount);
this.tvDateCV = (TextView) view.findViewById(R.id.tvDateCV);
// 리사이클러뷰의 각 아이템을 재사용하는 MyViewHolder 에서 각 아이템에 대한 클릭 리스너를 달 수 있다. : 필요시 사용
// MyViewHolder 가 리사이클러뷰의 각 뷰 항목을 만드는 역할을 하기 때문에, 여기서 작업을 해야한다.
view.setClickable(true);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pos = getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
// 데이터 리스트로부터 아이템 데이터 참조.
DataModel item = dataModelArrayList.get(pos);
getContentsNum = item.getContentsNum();
String getSection = item.getSection();
String getCategory = item.getCategory();
String getTitle = item.getTitle();
String getNickName = item.getNickName();
String getContents = item.getContents();
Bitmap getImage = item.getImage();
String getDate = item.getDate();
String getEmail = item.getEmail();
// 클릭한 리사이클러뷰의 내용을 인텐트에 담아서 이동할액티비티로 간다.
Intent intent = new Intent(context, ContentsActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("getContentsNum", getContentsNum);
intent.putExtra("getSection", getSection);
intent.putExtra("getCategory", getCategory);
intent.putExtra("getTitle", getTitle);
intent.putExtra("getNickName", getNickName);
intent.putExtra("getContents", getContents);
intent.putExtra("getImage", getImage);
intent.putExtra("getDate", getDate);
intent.putExtra("getEmail", getEmail);
context.startActivity(intent);
}
}
});
}
}
// 리스트 뷰가 어댑터에 연결된 다음 이쪽에서 뷰 홀더를 최초로 만들어 냄.
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Log.d(TAG, "태그 onCreateViewHolder 들어옴");
View cardView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cardview, parent, false); //view연결
MyViewHolder holder = new MyViewHolder(cardView);
return holder;
// 각각의 아이템을 위한 뷰를 담고있는 뷰홀더 객체를 반환한다.
// (각 아이템을 위한 XML 레이아웃을 이용해 뷰 객체를 만들었고 이걸 뷰홀더에서 참조할 수 있도록 위에 만들어 놓음)
}
// 각 아이템들에 대한 실제적인 매칭해주는 곳
// onBindViewHolder() - position 서로 결합되는 경우 해당하는 데이터를 뷰홀더의 아이템뷰에 표시.
// View 의 내용을 해당 포지션의 데이터로 바꿉니다.
// 각각의 아이템을 위한 뷰의 xml 레이아웃 호출(즉, 뷰홀더가 각각의 아이템을 위한 뷰를 담아주기 위한 용도인데, 뷰와 아이템이 합쳐질 때 호출)
// 적절한 데이터를 가져와서 뷰 소유자의 레이아웃을 채우기 위해서 사용(뷰홀더에 각 아이템의 데이터를 설정해 놓았음.)
@Override
public void onBindViewHolder(@NonNull MyRecyclerViewAdapter.MyViewHolder holder, int position) {
// 각 위치에 문자열 세팅
// 객체가 있는 배열에 담아서 어댑터 쪽으로 쏜다. 그걸 onBindViewHolder 가 받아서 Glide가 load하는 형태이다.
DataModel dataModelPosition = dataModelArrayList.get(position); // 데이터 리스트 객체에서 어떤거 가져올지 위치로 추출
holder.tvCategoryCV.setText(dataModelPosition.getCategory());
holder.tvTitleCV.setText(dataModelPosition.getTitle());
holder.tvContentsCV.setText(dataModelPosition.getContents());
holder.tvNickNameCV.setText(dataModelPosition.getNickName());
holder.tvHitCV.setText(dataModelPosition.getHit());
holder.tvCommentCount.setText(dataModelPosition.getComment());
holder.tvDateCV.setText(dataModelPosition.getDate());
holder.tvCommentCount.setText(dataModelPosition.getComment());
context = holder.itemView.getContext();
/* 리사이클러뷰의 버튼을 클릭할 때 실행될 것들을 적어준다. */
holder.ibLike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "리사이클러뷰의 좋아요 버튼이 눌렸습니다.", Toast.LENGTH_SHORT).show();
}
});
// Glide : 작성하면 이미지 load가 가능해진다. holder시 삽입될 것이다.
// override() : 해당 사이즈로 이미지를 늘리거나 줄이는 것.
// fitCenter() : 해당 이미지뷰의 크기가 지정되어 있을 경우 이미지 뷰의 크기에 이미지를 맞추는 것
Glide.with(context).load(dataModelArrayList.get(position).getImage()).fitCenter().into(holder.ivImageCV);
}
// 몇개의 데이터를 리스트로 뿌려줘야하는지 반드시 정의해줘야한다
@Override
public int getItemCount() {
// 삼항연산자 arrayList 가 null이면 왼쪽꺼 실행 아니면 오른쪽거 실행
return (dataModelArrayList != null ? dataModelArrayList.size() : 0);
}
}
- 리사이클러뷰에 보여줄 데이터를 담을 객체를 만들어 줍니다.
package com.Recyclerview;
import android.graphics.Bitmap;
public class DataModel {
Bitmap image; // 사진
String category; // 카테고리
String title; // 제목
String contents; // 내용
String nickName; // 닉네임
String email; // 이메일
String hit; // 조회수
String comment; // 댓글 수
String date; // 날짜
String section; //섹션(토픽인지, 직종인지)
String contentsNum; // 게시글 숫자
int likeCount; // 좋아요갯수
boolean userLiked; // 좋아요 눌린 여부
public DataModel( String contentsNum, String section, Bitmap image, String category, String title, String contents, String nickName, String hit, /*String comment,*/ String date, String email, int likeCount, boolean userLiked) {
this.image = image;
this.category = category;
this.title = title;
this.contents = contents;
this.nickName = nickName;
this.hit = hit;
this.comment = comment;
this.date = date;
this.email = email;
this.section = section;
this.contentsNum = contentsNum;
this.likeCount = likeCount;
this.userLiked = userLiked;
}
public Bitmap getImage() {
return image;
}
public String getCategory() {
return category;
}
public String getTitle() {
return title;
}
public String getContents() {
return contents;
}
public String getNickName() {
return nickName;
}
public String getHit() {
return hit;
}
public String getComment() {
return comment;
}
public String getDate() {
return date;
}
public String getEmail() {
return email;
}
public String getSection() {
return section;
}
public String getContentsNum() {
return contentsNum;
}
public int getLikeCount() {
return likeCount;
}
public boolean isUserLiked() {
return userLiked;
}
public void setUserLiked(boolean userLiked) {
this.userLiked = userLiked;
}
public void setLikeCount(int likeCount) {
this.likeCount = likeCount;
}
public void setImage(Bitmap image) {
this.image = image;
}
public void setCategory(String category) {
this.category = category;
}
public void setTitle(String title) {
this.title = title;
}
public void setContents(String contents) {
this.contents = contents;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public void setHit(String hit) {
this.hit = hit;
}
public void setComment(String comment) {
this.comment = comment;
}
public void setDate(String date) {
this.date = date;
}
public void setEmail(String email) {
this.email = email;
}
public void setSection(String setcion) {
this.section = section;
}
public void setContentsNum(String contentsNum) {
this.contentsNum = contentsNum;
}
}

- 프래그먼트의 onCreateView에서 앞서 정의한 xml을 인플레이션하고 그 ViewGroup의 객체로 recyclerView를 가져옵니다.
- 리사이클러뷰 연결, 리사이클러뷰에 어댑터 연결, 리사이클러뷰에 레이아웃 매니저 연결을 해 줍니다.
저는 getMysql() 이라는 메소드를 만들어서 데이터를 가지고 왔습니다.
서버를 사용하지 않는다면 이 부분에서 데이터를 추가해 주면 되겠죠?
프래그먼트 위에 이런식으로 카드뷰가 보여지게 됩니다!

'안드로이드 자바' 카테고리의 다른 글
[JAVA][Android] ViewModel, LiveData 활용하기 (0) | 2021.07.19 |
---|---|
[Java][Android] 원하는 시간에 알림 받기 (0) | 2021.07.17 |
[Java][Android] 카메라로 촬영해서 썸네일 띄우기 (3) | 2021.07.14 |
[Java][Android] OpenCV 를 사용해서 이미지 외곽선을 따는 기능을 만들어 보자 (0) | 2021.07.09 |
[Java][Android] MLKit를 이용한 텍스트 인식 (6) | 2021.07.07 |