ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

    1. Adapter 는 여러개의 item을 가지고 있으므로 ArrayList를 만들어 data를 넣을 수 있게 했다.
    2. ViewHoler를 담고있는 Adapter를 상속하도록 RecyclerView.Adapter<PersonAdapter.ViewHolder> 를 상속받았다.
    3. 필요한 세개의 메소드를 추가했다. 
    • 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

    몇가지 메서드를 추가했다.

    1. addItem() : Adapter에 Person 객체를 추가하기 위해
    2. setItems() : ArrayList 를 전체적으로 설정하기 위해
    3. getItem() : position 번째에 있는 item을 return 하기 위해
    4. 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
Designed by Tistory.