본문 바로가기
Android

[Android] 안드로이드 : 리스트뷰(ListView) 만들기

by 꿈나무 김땡땡 2019. 12. 3.

1. 리스트뷰란?

- 리스트뷰는 여러 개의 아이템을 위, 아래로 스크롤할 수 있게 해주면 그 안에 들어가 있는 각각의 아이템을 순서대로 보여주는 뷰

- 각각의 아이템은 독립적인 뷰로 만들어지게 되고 이 뷰들이 모여있는 형태를 유지해 주는 것이 리스트뷰

 

* 주의할 점은 리스트 아이템의 데이터는 리스트뷰가 관리하는 것이 아니라 어댑터에서 관리

그리고 어댑터를 리스트뷰에 설정하면 리스트뷰는 어댑터에게 데이터나 각각의 아이템을 위한 뷰에 관해 물어보게 됩니다.

각각의 아이템을 위한 뷰도 어댑터에서 만들어주기 때문에 리스트뷰는 어댑터의 getView 메소드를 호출하여 뷰 객체를 반환받은 후 화면에 보여주게 됩니다.

 

 

2. 리스트뷰 만들기

 

(1) 아이템을 위한 XML 레이아웃 정의

  - 리스트뷰에 들어갈 각 아이템의 레이아웃을 XML로 정의

(2) 아이템을 위한 뷰 정의

  - 리스트뷰에 들어갈 각 아이템을 하나의 뷰로 정의.이 뷰는 여러 개의 뷰를 담고 있는 뷰그룹이어야 함

  - 이것은 부분화면과 같아서 (1)에서 정의한 XML 레이아웃을 인플레이션 후 설정해야 함

(3) 어댑터 정의

  - 데이터 관리 역할을 하는 어댑터 클래스를 만들고, 그 안에 각 아이템으로 표시할 뷰를 리턴하는 getView() 메소드를 정의

(4) 리스트뷰 정의

  - 화면에 보여줄 리스트뷰를 만들고, 그 안에 데이터가 선택되었을 때 호출될 리스너 객체를 정의

 

3. 리스트뷰 만들기 예제

(1) activity_main.xml에 listView 만들기

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="추가" />

        <EditText
            android:id="@+id/editText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:inputType="textPersonName"
            android:text="소녀시대" />

        <EditText
            android:id="@+id/editText2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:inputType="textPersonName"
            android:text="010-232-4232" />

    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="687dp"
        android:layout_below="@+id/linearLayout"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginTop="0dp"/>

</RelativeLayout>

(2) MainActivity.java에 listView 호출 + Adapter 만들기

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    SingerAdapter adapter;

    EditText editText;
    EditText editText2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);
        editText2 = (EditText) findViewById(R.id.editText2);

        ListView listView = (ListView) findViewById(R.id.listView);

        // 어댑터 안에 데이터 담기
        adapter = new SingerAdapter();

        adapter.addItem(new SingerItem("소녀시대", "010-3433-2323", R.drawable.android1));
        adapter.addItem(new SingerItem("소녀시대2", "010-3433-2323", R.drawable.android2));
        adapter.addItem(new SingerItem("소녀시대3", "010-3433-2323", R.drawable.android3));
        adapter.addItem(new SingerItem("소녀시대4", "010-3433-2323", R.drawable.android4));
        adapter.addItem(new SingerItem("소녀시대5", "010-3433-2323", R.drawable.android5));
        adapter.addItem(new SingerItem("소녀시대6", "010-3433-2323", R.drawable.android6));

        // 리스트 뷰에 어댑터 설정
        listView.setAdapter(adapter);

        // 이벤트 처리 리스너 설정
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                SingerItem item = (SingerItem) adapter.getItem(position);
                Toast.makeText(getApplicationContext(), "선택 :"+item.getName(), Toast.LENGTH_LONG).show();
            }
        });

        // 버튼 눌렀을 때 우측 이름, 전화번호가 리스트뷰에 포함되도록 처리
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = editText.getText().toString();
                String mobile = editText2.getText().toString();

                adapter.addItem(new SingerItem(name, mobile, R.drawable.android1));
                adapter.notifyDataSetChanged();
            }
        });
    }

    class SingerAdapter extends BaseAdapter {
        ArrayList<SingerItem> items = new ArrayList<SingerItem>();


        // Generate > implement methods
        @Override
        public int getCount() {
            return items.size();
        }

        public void addItem(SingerItem item) {
            items.add(item);
        }

        @Override
        public Object getItem(int position) {
            return items.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }


        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // 뷰 객체 재사용
            SingerItemView view = null;
            if (convertView == null) {
                view = new SingerItemView(getApplicationContext());
            } else {
                view = (SingerItemView) convertView;
            }

            SingerItem item = items.get(position);

            view.setName(item.getName());
            view.setMobile(item.getMobile());
            view.setImage(item.getResId());


            return view;
        }
    }
}

(3) SingerItem.java 만들기 : 아이템에 넣을 속성 정의하기

package org.techtown.list;

// 걸그룹 데이터 담기
public class SingerItem {
    String name;
    String mobile;
    int resId;

    // Generate > Constructor
    public SingerItem(String name, String mobile, int resId) {
        this.name = name;
        this.mobile = mobile;
        this.resId = resId;
    }

    // Generate > Getter and Setter
    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) {
        this.resId = resId;
    }

    // Generate > toString() : 아이템을 문자열로 출력

    @Override
    public String toString() {
        return "SingerItem{" +
                "name='" + name + '\'' +
                ", mobile='" + mobile + '\'' +
                '}';
    }
}

(4) singer_item.xml 만들기 : 아이템을 위한 뷰 정의하기 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@mipmap/ic_launcher"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="10dp">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="이름"
            android:textSize="30sp"
            android:textColor="@color/colorPrimaryDark"/>

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="전화번호"
            android:textSize="24sp"
            android:textColor="@android:color/holo_orange_dark"/>

    </LinearLayout>

</LinearLayout>

(5) singerItemView.java 만들기 : 아이템을 위한 뷰 정의하기

(뷰는 xml 파일 1개 + java 파일 1개)

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;

public class SingerItemView extends LinearLayout {

    TextView textView;
    TextView textView2;
    ImageView imageView;

    // Generate > Constructor

    public SingerItemView(Context context) {
        super(context);

        init(context);
    }

    public SingerItemView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        init(context);
    }

    // singer_item.xml을 inflation
    private void init(Context context) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.singer_item, this, true);

        textView = (TextView) findViewById(R.id.textView);
        textView2 = (TextView) findViewById(R.id.textView2);
        imageView = (ImageView) findViewById(R.id.imageView);
    }

    public void setName(String name) {
        textView.setText(name);
    }

    public void setMobile(String mobile) {
        textView2.setText(mobile);
    }

    public void setImage(int resId) {
        imageView.setImageResource(resId);
    }

}

 

예시 화면

댓글