[Android] ListView 사용하기 View 커스터마이징

Krrong·2022년 5월 4일
0

Android

목록 보기
2/14
post-thumbnail
post-custom-banner

📌 Intro

이전 글에서는 간단하게 텍스트만 출력하는 ListView 사용방법을 알아보았다. 이번에는 다양한 View가 합쳐진 View를 출력하는 ListView를 어떻게 사용하는지 알아보도록 하자.
만약 ListView를 어떻게 사용하는지 모른다면 이글을 먼저 보고 오면 좋을 것 같다.
앞으로의 설명도 이글을 기반으로 설명할 예정이다.


📌 ListView 사용하기

1. item_list.xml 레이아웃 생성

ListView에 데이터를 어떻게 보여줄 것인지 정의하는 레이아웃인 item_list.xml 파일을 만들어준다.
내가 정의한 xml의 코드와 design은 아래와 같다.

<?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">

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

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

        <TextView
            android:id="@+id/text_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30sp"
            android:text="TextView" />

        <TextView
            android:id="@+id/text_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:text="TextView" />
    </LinearLayout>

</LinearLayout>


2. SingleItem.java

아이템을 구성하는 SingleItem 클래스를 정의한다. 아이템 하나를 구성하는 요소는 앞에서 디자인한 레이아웃과 같이 텍스트 2개와 이미지 1개다. 그렇기 때문에 SingleItem 클래스 안에 변수 3개를 만들어 관리할 것이다.
ListView는 list형태의 데이터가 필요하기 때문에 ArrayList에 저장하기 위한 SingleItem 클래스를 만들어주는 것이라고 생각하면 된다.

public class SingleItem {
    private String name;    // 이름
    private String price;   // 가격
    private int resId;      // 이미지 번호

    // 생성자
    public SingleItem(String name, String price, int resId){
        this.name = name;
        this.price = price;
        this.resId = resId;
    }
    
    public void setName(String name){
        this.name = name;
    }
    public void setPrice(String price){
        this.price = price;
    }
    public void setResId(int resId){
        this.resId = resId;
    }
    
    public String getName(){
        return this.name;
    }
    public String getPrice(){
        return this.price;
    }
    public int getResId(){
        return this.resId;
    }
}



3. SingleItemAdapter.java

데이터를 각각의 View에 연결 시켜줄 어댑터를 만들어줘야 한다. Adapter는 BaseAdapter를 상속 받아 만들고 기본적으로 만들어야 하는 함수가 있다.

  • int getCount()
    데이터의 개수를 리턴해준다.

  • Object getItem(int position)
    position위치에 있는 아이템을 리턴해준다.

  • long getItemId(int position)
    position위치에 있는 아이템의 ID를 리턴해준다.

  • View getView(int position, View view, ViewGroup parent)
    각 아이템을 표시할 View를 리턴해준다.

그리고 나는 데이터를 SingleItem형태로 관리하고 ListView에 넣어줄 것이기 때문에 데이터를 담는 리스트를 ArrayList<SingleItem>으로 선언해주어야 한다.

package com.example.test;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

public class SingleItemAdapter extends BaseAdapter {
    private Context context;
    private ArrayList<SingleItem> array_singleItem = new ArrayList<>();

    // 생성자
    public SingleItemAdapter(ArrayList<SingleItem> array_singleItem, Context context) {
        this.context = context;
        this.array_singleItem = array_singleItem;
    }

    // 데이터 개수 리턴
    @Override
    public int getCount() {
        return array_singleItem.size();
    }

    // position 위치의 아이템 리턴
    @Override
    public Object getItem(int position) {
        return array_singleItem.get(position);
    }

    // position 위치 아이템의 id 리턴
    @Override
    public long getItemId(int position) {
        return position;
    }

    // i번째 아이템을 어떻게 보여줄 것인지 결정
    @Override
    public View getView(int position, View view, ViewGroup parent) {
        // LayoutInflater를 통해 layout파일 메모리에 객체화
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.item_list, parent, false);

        // 각 view의 내용 설정
        TextView name = view.findViewById(R.id.text_name);
        name.setText(array_singleItem.get(position).getName());

        TextView price = view.findViewById(R.id.text_price);
        price.setText(array_singleItem.get(position).getPrice());

        ImageView image = view.findViewById(R.id.imageView);
        image.setImageResource(array_singleItem.get(position).getResId());

        // view 반환
        return view;
    }
}



4. ListView와 Adapter 연결

마지막으로 ListView를 띄워줄 Activity에서 ListView와 Adapter를 연결해주도록 한다.

package com.example.test;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    ListView listView;

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

        // listView binding
        listView = findViewById(R.id.listView);

        // 데이터를 담을 List
        ArrayList<SingleItem> itemList = new ArrayList<SingleItem>();

        // 데이터 추가
        itemList.add(new SingleItem("아이템 1", "1000원", R.drawable.ic_launcher_background));
        itemList.add(new SingleItem("아이템 2", "2000원", R.drawable.ic_launcher_background));
        itemList.add(new SingleItem("아이템 3", "3000원", R.drawable.ic_launcher_background));

        // adapter 생성
        SingleItemAdapter adapter = new SingleItemAdapter(itemList, getApplicationContext());

        // listView에 adapter 연결
        listView.setAdapter(adapter);
    }
}

이전과 달라진 점은 데이터를 담는 itemList를 SingleItem객체를 담을 수 있도록 선언했다는 것과 SingleItem데이터를 사용하기 위해 SingleItemAdapter를 재정의하고 Adapter로 사용했다는 것이다.

이처럼 어렵지 않게 각자가 원하는 view를 커스터마이징하여 ListView를 사용할 수 있다.


5. 실행화면

📌 참고

[1] https://ju-hy.tistory.com/35

post-custom-banner

0개의 댓글