오늘이라도
[Android] 22. 리사이클러 뷰(Recycler View) ① : 리사이클러 뷰, 어댑터 작성, 클릭 이벤트 추가 / ② : 클릭 이벤트 인터페이스 작성, 버튼 눌러서 항목 추가 본문
취업성공패키지 SW 개발자 교육/Android
[Android] 22. 리사이클러 뷰(Recycler View) ① : 리사이클러 뷰, 어댑터 작성, 클릭 이벤트 추가 / ② : 클릭 이벤트 인터페이스 작성, 버튼 눌러서 항목 추가
upcake_ 2020. 6. 4. 11:26반응형
https://github.com/upcake/Class_Examples
교육 중에 작성한 예제들은 깃허브에 올려두고 있습니다.
gif 파일은 클릭해서 보는 것이 정확합니다.
- 리사이클러 뷰(Recycler View) ① : 리사이클러 뷰, 어댑터 작성, 클릭 이벤트 추가 -
▼activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
▼MainActivity.java
package com.example.my29_recylerview;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
//Ctrl + p를 누르면 받아야할 매개 변수가 무엇인지 보여준다.
LinearLayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
PersonAdapter adapter = new PersonAdapter();
adapter.addItem(new PersonDTO("가수1", "010-1111-1111", R.drawable.singer1));
adapter.addItem(new PersonDTO("가수2", "010-2222-2222", R.drawable.singer2));
adapter.addItem(new PersonDTO("가수3", "010-3333-3333", R.drawable.singer3));
adapter.addItem(new PersonDTO("가수4", "010-4444-4444", R.drawable.singer4));
adapter.addItem(new PersonDTO("가수5", "010-5555-5555", R.drawable.singer5));
recyclerView.setAdapter(adapter);
}
}
▼PersonDTO.java
package com.example.my29_recylerview;
public class PersonDTO {
String name;
String phoneNum;
int resId;
public PersonDTO() {
}
public PersonDTO(String name, String phoneNum, int resId) {
this.name = name;
this.phoneNum = phoneNum;
this.resId = resId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public int getResId() {
return resId;
}
public void setResId(int resId) {
this.resId = resId;
}
}
▼person_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true">
<!--CornerRadius : 모서리 깎기-->
<!--cardElevation : 부유 효과-->
<LinearLayout
android:id="@+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:padding="5dp"
android:src="@drawable/singer1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="vertical"
android:layout_margin="5dp">
<TextView
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="이름"
android:textSize="30sp" />
<!--dp는 레이아웃의 크기를 지정할 때, sp는 텍스트의 크기를 지정할 때 사용한다.-->
<!--화면에서 언제나 똑같은 크기의 글자를 보여주고자할때는 dp를 텍스트에 사용해도 된다.-->
<TextView
android:id="@+id/tvPhoneNum"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="전화번호"
android:textSize="25sp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
▼PersonAdapter.java
package com.example.my29_recylerview;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
//리사이클러뷰 어댑터를 상속받는다.
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder> {
ArrayList<PersonDTO> itemList = new ArrayList<>();
private static final String TAG = "MainPersonAdapter";
//뷰홀더가 만들어질때 작동하는 메서드
//화면을 인플레이트하고 인플레이트된 화면을 리턴한다.
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.person_item, parent, false);
return new ViewHolder(itemView);
}
//뷰홀더가 생길때 dto를 뷰홀더에 넘겨준다.
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: position ▶ " + position);
PersonDTO item = itemList.get(position);
holder.setItem(item);
//이름 텍스트뷰 클릭했을 때 로그캣에 이름 출력
holder.tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: " + itemList.get(position).getName());
}
});
//레이아웃 내부의 아무곳이나 클릭했을 때 로그캣에 전화번호 출력
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: " + itemList.get(position).phoneNum);
}
});
}
//아이템이 몇 개 들어갔는지 세는 메서드
@Override
public int getItemCount() {
return itemList.size();
}
public void addItem(PersonDTO item) {
itemList.add(item);
}
//리사이클러뷰 뷰홀더를 상속받는다.
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvName, tvPhoneNum;
ImageView imageView;
LinearLayout parentLayout;
//생성자를 만든다.
//여기서 itemView는 화면에 표시되는 각각의 person_item.xml 뷰이다
public ViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tvName);
tvPhoneNum = itemView.findViewById(R.id.tvPhoneNum);
imageView = itemView.findViewById(R.id.imageView);
parentLayout = itemView.findViewById(R.id.parentLayout);
}
public void setItem(PersonDTO item) {
tvName.setText(item.getName());
tvPhoneNum.setText(item.getPhoneNum());
imageView.setImageResource(item.getResId());
}
}
}
- 리사이클러 뷰(Recycler View) ② : 클릭 이벤트 인터페이스 작성, 버튼 눌러서 항목 추가 -
DTO와 person_item.xml은 ① 코드를 같이 사용한다.
▼activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="추가"
android:textSize="24sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
▼MainActivity.java
package com.example.my30_recylerview2;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.Person;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
RecyclerView recyclerView;
Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
//Ctrl + p를 누르면 받아야할 매개 변수가 무엇인지 보여준다.
LinearLayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
final PersonAdapter adapter = new PersonAdapter();
adapter.addItem(new PersonDTO("가수1", "010-1111-1111", R.drawable.singer1));
adapter.addItem(new PersonDTO("가수2", "010-2222-2222", R.drawable.singer2));
adapter.addItem(new PersonDTO("가수3", "010-3333-3333", R.drawable.singer3));
adapter.addItem(new PersonDTO("가수4", "010-4444-4444", R.drawable.singer4));
adapter.addItem(new PersonDTO("가수5", "010-5555-5555", R.drawable.singer5));
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(new OnPersonDTOItemClickListener() {
@Override
public void onItemClick(PersonAdapter.ViewHolder holderm, View view, int position) {
PersonDTO item = adapter.getItem(position);
Log.d(TAG, "onItemClick: " + item.getName());
}
});
button1 = findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PersonDTO item = new PersonDTO("가수6", "010-6666-6666", R.mipmap.ic_launcher);
adapter.addItem(item);
adapter.notifyDataSetChanged();
}
});
}
}
▼PersonAdapter.java
package com.example.my30_recylerview2;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
//리사이클러뷰 어댑터를 상속받는다.
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder> implements OnPersonDTOItemClickListener{
ArrayList<PersonDTO> itemList = new ArrayList<>();
private static final String TAG = "MainPersonAdapter";
OnPersonDTOItemClickListener listener;
//뷰홀더가 만들어질때 작동하는 메서드
//화면을 인플레이트하고 인플레이트된 화면을 리턴한다.
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.person_item, parent, false);
return new ViewHolder(itemView, listener);
}
//뷰홀더가 생길때 dto를 뷰홀더에 넘겨준다.
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: position ▶ " + position);
PersonDTO item = itemList.get(position);
holder.setItem(item);
}
//아이템이 몇 개 들어갔는지 세는 메서드
@Override
public int getItemCount() {
return itemList.size();
}
//리스트에 DTO를 추가하는 메서드
public void addItem(PersonDTO item) {
itemList.add(item);
}
//리스트의 해당 인덱스의 DTO 객체를 반환하는 메서드
public PersonDTO getItem(int position) {
return itemList.get(position);
}
public void setOnItemClickListener(OnPersonDTOItemClickListener listener) {
this.listener = listener;
}
@Override
public void onItemClick(ViewHolder holderm, View view, int position) {
if(listener != null){
listener.onItemClick(holderm, view, position);
}
}
//리사이클러뷰 뷰홀더를 상속받는다.
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvName, tvPhoneNum;
ImageView imageView;
//생성자를 만든다.
//여기서 itemView는 화면에 표시되는 각각의 person_item.xml 뷰이다
public ViewHolder(@NonNull View itemView, final OnPersonDTOItemClickListener listener) {
super(itemView);
tvName = itemView.findViewById(R.id.tvName);
tvPhoneNum = itemView.findViewById(R.id.tvPhoneNum);
imageView = itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = getAdapterPosition();
if(listener != null) {
listener.onItemClick(ViewHolder.this, view, position);
}
}
});
}
public void setItem(PersonDTO item) {
tvName.setText(item.getName());
tvPhoneNum.setText(item.getPhoneNum());
imageView.setImageResource(item.getResId());
}
}
}
▼OnPersonDTOItemClickListener
package com.example.my30_recylerview2;
import android.view.View;
public interface OnPersonDTOItemClickListener {
public void onItemClick(PersonAdapter.ViewHolder holderm, View view, int position);
}
반응형