-
RecyclerView를 이용해서 list 만들기Android 2021. 7. 8. 00:44
<?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"> <LinearLayout android:id="@+id/layout1" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/editText" android:hint="이름" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/editText2" android:hint="전화번호" /> </LinearLayout> <LinearLayout android:id="@+id/layout2" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText3" android:hint="생년월일" /> </LinearLayout> <RelativeLayout android:id="@+id/layout3" android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="추가" android:id="@+id/button" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignBaseline="@+id/button" android:layout_marginRight="14dp" android:text="0명" android:textColor="#000000" android:textSize="14dp" android:id="@+id/textView" /> </RelativeLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
activity_main.xml
xml에 RecyclerView를 추가하면 item 들이 가상으로 보인다. 각 item을 위한 class를 만들어서 그 class를 ArrayList에 담아서 관리해야한다.
그 class 를 만들어보자.
public class Person { String name; String mobile; String birth; int ResId; public Person(String name, String mobile,String birth,int ResId) { this.name = name; this.mobile = mobile; this.ResId = ResId; this.birth = birth; } public String getBirth() { return birth; } public void setBirth(String birth) { this.birth = birth; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public int getResId() { return ResId; } public void setResId(int resId) { ResId = resId; } }
Person.java
연락처 하나를 이 Person class 에 정의한다. (한 item을 위한 data 라고 생각하면 된다.)
data를 담아두기 위한 목적이니 getter, setter 를 추가한다.
이제 Person 에 data를 넣을 수 있고, 그 data는 adapter에 넣어야 한다.
RecyclerView 는 선택 위젯이고 눈에 보이는 모양을 담당한다.
실제 데이터 관리는 adapter를 사용한다.
adapter를 만들어보자.
public class PersonAdapter { static class ViewHolder extends RecyclerView.ViewHolder{ TextView textView1; TextView textView2; TextView textView3; ImageView imageView; public ViewHolder(View itemView,final OnPersonItemClickListener listener) { super(itemView); textView1 = itemView.findViewById(R.id.textView1); textView2 = itemView.findViewById(R.id.textView2); textView3 = itemView.findViewById(R.id.textView3); imageView = itemView.findViewById(R.id.imageView); public void setItem(Person item){ textView1.setText(item.getName()); textView2.setText(item.getBirth()); textView3.setText(item.getMobile()); imageView.setImageResource(item.getResId()); } } }
personAdapter.java
RecyclerView.ViewHolder 를 상속한 ViewHolder 클래스를 만들었다. ViewHolder는 각 item을 위한 뷰를 담는 역할이다. 재사용이 가능하다.
ViewHolder 생성자 함수도 만들었다. 이 생성자에는 View 객체가 전달되고, 전달 받은 객체를 부모 클래스의 변수에 담아두게 되는데 생성자 안에서 super() 메서드를 호출하면 된다.
그리고 방금 만든 Person 데이터를 View 에 보여주는 역할을 하는 setItem 메서드를 만들었다.
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder>{ ArrayList<Person> items = new ArrayList<>(); @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); //LayoutInflater 객체 참조. View itemView = inflater.inflate(R.layout.person_item,parent,false); //각 item을 위한 View를 만들었다. return new ViewHolder(itemView,this); //우리가 만든 ViewHolder에 itemView를 전달한다. } @Override public void onBindViewHolder(ViewHolder holder, int position) { Person item = items.get(position); holder.setItem(item); } @Override public int getItemCount() { return items.size(); } ... static class ViewHolder extends RecyclerView.ViewHolder{ TextView textView1; TextView textView2; TextView textView3; ImageView imageView; public ViewHolder(View itemView,final OnPersonItemClickListener listener) { super(itemView); textView1 = itemView.findViewById(R.id.textView1); textView2 = itemView.findViewById(R.id.textView2); textView3 = itemView.findViewById(R.id.textView3); imageView = itemView.findViewById(R.id.imageView); } public void setItem(Person item){ textView1.setText(item.getName()); textView2.setText(item.getBirth()); textView3.setText(item.getMobile()); imageView.setImageResource(item.getResId()); } } }
personAdapter.java
- Adapter 는 여러개의 item을 가지고 있으므로 ArrayList를 만들어 data를 넣을 수 있게 했다.
- ViewHoler를 담고있는 Adapter를 상속하도록 RecyclerView.Adapter<PersonAdapter.ViewHolder> 를 상속받았다.
- 필요한 세개의 메소드를 추가했다.
- getItemCount() : items 에 들어있는 개수를 return 받기 위한 함수이다.
- onCreateViewHolder() : ViewHolder 가 생성되는 시점에 자동으로 실행된다. (item 을 위한 layout을 이 안에서 inflation한다. -> inflation 한 View를 ViewHolder에 넣는다. -> 그 ViewHolder를 return한다. -> 하나의 item을 위한 ViewHolder가 만들어져서 return 된다.)
- onBindViewHoler() : 스크롤을 내리거나 올릴 때, 화면에서 벗어나는 ViewHoler를 재사용할 건데, 그 사용했었던 ViewHoler를 parameter로 전달 받는다.
각 View를 위한 layout을 만들자.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" 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"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_margin="8dp"> <ImageView android:id="@+id/imageView" android:layout_width="80dp" android:layout_height="80dp" android:padding="5dp" app:srcCompat="@drawable/img4" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:duplicateParentState="true" android:text="name" android:textColor="#009688" android:textSize="30sp" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentBottom="true" android:text="birth" android:textColor="#FF9800" android:textSize="15sp" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:text="mobile" android:textColor="#3F51B5" android:textSize="15sp" /> </RelativeLayout> </LinearLayout> </LinearLayout> </androidx.cardview.widget.CardView> </LinearLayout>
person_item.xml
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder> { ArrayList<Person> items = new ArrayList<>(); OnPersonItemClickListener listener; ... public void addItem(Person item){ items.add(item); } public void setItems(ArrayList<Person> items){ this.items = items; } public Person getItem(int position){ return items.get(position); } public void setItem(int position,Person item){ items.set(position,item); } @Override public void onItemClick(ViewHolder holder, View view, int position) { listener.onItemClick(holder,view,position); } public void setOnItemClickListener(OnPersonItemClickListener listener) { this.listener = listener; } static class ViewHolder extends RecyclerView.ViewHolder{ TextView textView1; TextView textView2; TextView textView3; ImageView imageView; public ViewHolder(View itemView,final OnPersonItemClickListener listener) { super(itemView); textView1 = itemView.findViewById(R.id.textView1); textView2 = itemView.findViewById(R.id.textView2); textView3 = itemView.findViewById(R.id.textView3); imageView = itemView.findViewById(R.id.imageView); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = getAdapterPosition(); listener.onItemClick(ViewHolder.this,v,position); } }); } public void setItem(Person item){ textView1.setText(item.getName()); textView2.setText(item.getBirth()); textView3.setText(item.getMobile()); imageView.setImageResource(item.getResId()); } } }
PersonAdapter.java
몇가지 메서드를 추가했다.
- addItem() : Adapter에 Person 객체를 추가하기 위해
- setItems() : ArrayList 를 전체적으로 설정하기 위해
- getItem() : position 번째에 있는 item을 return 하기 위해
- setItem()
이제 MainActivity에 RecyclerView 를 설정해보자.
public class MainActivity extends AppCompatActivity { EditText editText1; EditText editText2; EditText editText3; TextView textView; RecyclerView recyclerView; PersonAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText1 = findViewById(R.id.editText); editText2 = findViewById(R.id.editText2); editText3 = findViewById(R.id.editText3); textView = findViewById(R.id.textView); recyclerView = findViewById(R.id.recyclerView); LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false); //RecyclerView 에 레이아웃 매니저 설정 //GridLayoutManager layoutManager = new GridLayoutManager(this,2); recyclerView.setLayoutManager(layoutManager); adapter = new PersonAdapter(); adapter.addItem(new Person("피아지","1990-01-01","010-1111-1111",R.drawable.img4)); //실제 Person 객체 넣기 adapter.addItem(new Person("손아지","1990-11-01","010-1111-1234",R.drawable.img4)); recyclerView.setAdapter(adapter); } }
MainActivity.java
item을 눌렀을 때 동작하도록 해보자. 버튼을 눌렀을 때 동작할 함수를 약속할 interface를 만들자.
public interface OnPersonItemClickListener { public void onItemClick(PersonAdapter.ViewHolder holder, View view, int position); }
OnPersonItemClickListener.java
item이 클릭되면 onItemClick 함수가 호출된다.
ViewHolder에도 item이 클릭되었을 때 기능을 추가해야한다.
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder> implements OnPersonItemClickListener{ ArrayList<Person> items = new ArrayList<>(); OnPersonItemClickListener listener; @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View itemView = inflater.inflate(R.layout.person_item,parent,false); return new ViewHolder(itemView,this); } @Override public void onBindViewHolder(ViewHolder holder, int position) { Person item = items.get(position); holder.setItem(item); } @Override public int getItemCount() { return items.size(); } public void addItem(Person item){ items.add(item); } public void setItems(ArrayList<Person> items){ this.items = items; } public Person getItem(int position){ return items.get(position); } public void setItem(int position,Person item){ items.set(position,item); } @Override public void onItemClick(ViewHolder holder, View view, int position) { listener.onItemClick(holder,view,position); } public void setOnItemClickListener(OnPersonItemClickListener listener) { this.listener = listener; } static class ViewHolder extends RecyclerView.ViewHolder{ TextView textView1; TextView textView2; TextView textView3; ImageView imageView; public ViewHolder(View itemView,final OnPersonItemClickListener listener) { super(itemView); textView1 = itemView.findViewById(R.id.textView1); textView2 = itemView.findViewById(R.id.textView2); textView3 = itemView.findViewById(R.id.textView3); imageView = itemView.findViewById(R.id.imageView); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = getAdapterPosition(); listener.onItemClick(ViewHolder.this,v,position); } }); } public void setItem(Person item){ textView1.setText(item.getName()); textView2.setText(item.getBirth()); textView3.setText(item.getMobile()); imageView.setImageResource(item.getResId()); } } }
personAdapter.java
ViewHoler가 만들어지는 시점에 final OnPersonItemClicklistener listener 를 같이 전달받도록 하자.
그리고 이벤트 처리를 할건데, 이벤트 처리를 listener쪽으로 전달할 것이다.
그리고 OnPersonItemClickListener interface를 상속받아서 onItemClick과 setOnItemClickListener 메소드를 재정의해야한다.
public class MainActivity extends AppCompatActivity { EditText editText1; EditText editText2; EditText editText3; TextView textView; RecyclerView recyclerView; PersonAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText1 = findViewById(R.id.editText); editText2 = findViewById(R.id.editText2); editText3 = findViewById(R.id.editText3); textView = findViewById(R.id.textView); recyclerView = findViewById(R.id.recyclerView); LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false); recyclerView.setLayoutManager(layoutManager); adapter = new PersonAdapter(); adapter.addItem(new Person("피아지","1990-01-01","010-1111-1111",R.drawable.img4)); adapter.addItem(new Person("손아지","1990-11-01","010-1111-1234",R.drawable.img4)); recyclerView.setAdapter(adapter); adapter.setOnItemClickListener(new OnPersonItemClickListener() { @Override public void onItemClick(PersonAdapter.ViewHolder holder, View view, int position) { Person item = adapter.getItem(position); Toast.makeText(getApplicationContext(),"선택정보 : " + item.getName(),Toast.LENGTH_LONG).show(); } }); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { adapter.addItem(new Person(editText1.getText().toString(),editText2.getText().toString(),editText3.getText().toString(),R.drawable.img4)); adapter.notifyDataSetChanged(); recyclerView.setAdapter(adapter); textView.setText(adapter.getItemCount()+"명"); } }); textView.setText(adapter.getItemCount()+"명"); } }
MainActivity.java
728x90'Android' 카테고리의 다른 글
LinearLayout 상속하여 직접 만들기 (0) 2021.07.07 Button 을 상속하여 직접 만들기 (0) 2021.07.07 setTextSize() (0) 2021.07.07 Animation (0) 2021.07.06