[베다니 도서관] 4. 나만의 리스트뷰를 만들어보자



기존의 리스트뷰를 적용하면 우리가 많이 보는 모양이 나온다. 예를 들어 아래와 같은 모양 말이다.



하지만 가끔. 이미지가 들어가거나, 칸이 나누어져 있거나, 텍스트 밑에 부가 설명이 들어가있는 등 다양한 형태의 리스트뷰가 필요할 때도 있다. 이를 위해 커스텀 리스트뷰를 만들어서 적용할 수 있다.
커스텀 리스트뷰를 만들기 위해선 3가지가 필요하다.
  • 커스텀 리스트뷰에 들어가는 데이터의 정보
  • 커스텀 리스트뷰 레이아웃 디자인
  • 커스텀 리스트뷰 어댑터
하나씩 살펴보도록 하자.


1. 커스텀 리스트뷰에 들어가는 데이터의 정보

어떤 데이터가 어떤 타입이나 형태로 들어가는지 정하는 건 매우 간단하다. 아래와 같이 getter, setter를 이용해준다.




소스코드

package com.example.bethanylibrary;

public class CustomListItem {

    public String name;
    public String number;
    public String position;

    public String getName() {
        return name;
    }

    public String getNumber() {
        return number;
    }

    public String getPosition() {
        return position;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public void setPosition(String position) {
        this.position = position;
    }
}




2. 커스텀 리스트뷰 레이아웃 디자인

리스트뷰의 1행의 디자인을 바꿔줘서 그걸 리스트뷰에 집어넣는 방식이다. 그러기 위해선 1행의 디자인을 만들어줘야한다.

xml의 너비, 높이 같은 속성들은 화면에 끌어다 놓으면 자동으로 설정되니까  넘어가고 기본적인 것만 설명하겠다.

Layout 방식

  • LinearLayout : 가장 기본적인 속성으로, 위치를 지정하지 않으면 화면 왼쪽 구석에 전부 배치된다. 마우스로 끌어다놓기만 해줘도 된다.
  • RelativeLayout : 어떤 위젯을 기준으로 하여 그 위젯의 상, 하, 좌, 우로 배치하는 방식.
  • FrameLayout : Frame 위치에 위젯을 다 쌓아버리는 방식. 보통 로딩 중 화면이 떴다가 로딩이 끝난 화면을 보여줄 때 사용된다.
  • ConstraintLayout : 위젯 간의 위치에 따라 포지셔닝 하는 레이아웃인데, 아직 제대로 써본 적이 없어서 보류하겠다.

 속성
  • gravity : 상대적인 위치를 정해줌.
  • id : 레이아웃의 id를 지정해줌.

그 외에도 여러가지 있지만, 디자인 관련 속성은 그때 그때 알아보도록 하고, 여기서는 넘어가도록 하자.
일단 최종 디자인은 아래와 같다.




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

    <linearlayout 
        android:layout_height="50dp" 
        android:layout_width="match_parent" 
        android:orientation="horizontal">

        <textview 
             android:gravity="left|center" 
             android:id="@+id/bookname" 
             android:layout_height="match_parent" 
             android:layout_width="342dp" 
             android:text="책제목이 들어가는 자리입니다. 제목이 충분히 길어도 됩니다." 
             android:textcolor="#000000" 
             android:textsize="15dp">

        <linearlayout 
             android:layout_height="match_parent" 
             android:layout_weight="1" 
             android:layout_width="wrap_content" 
             android:orientation="vertical">

            <textview 
                 android:gravity="center" 
                 android:id="@+id/booknumber" 
                 android:layout_height="28dp" 
                 android:layout_width="match_parent" 
                 android:text="1234567" 
                 android:textcolor="#000000" 
                 android:textsize="15dp">

            <textview 
                 android:gravity="center" 
                 android:id="@+id/bookposition" 
                 android:layout_height="64dp" 
                 android:layout_weight="1" 
                 android:layout_width="match_parent" 
                 android:text="집단 지도실 2" 
                 android:textcolor="#666666" 
                 android:textsize="10dp">
        </linearlayout> 
    </linearlayout> 
</linearlayout> 


단순히 "제목" 텍스트 옆에 작은 "번호" 텍스트와 그 밑에 "위치" 텍스트가 들어가게 된다.


3. 커스텀 리스트뷰 어댑터

일단 코드는 아래와 같다.


소스코드

package com.example.bethanylibrary;

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

import java.util.ArrayList;

public class CustomAdapter extends BaseAdapter {

    private ArrayList mItems = new ArrayList<>();

    public CustomAdapter(ArrayList listitem){
        mItems = listitem;
    }

    @Override
    public int getCount() {
        return mItems.size();
    }

    @Override
    public CustomListItem getItem(int position) {
        return mItems.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        Context context = parent.getContext();

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.list_ui, parent, false);
        }

        TextView bookName = (TextView) convertView.findViewById(R.id.bookname);
        TextView bookNumber = (TextView) convertView.findViewById(R.id.booknumber);
        TextView bookPos = (TextView) convertView.findViewById(R.id.bookposition);

        CustomListItem myItem = getItem(position);

        bookName.setText(myItem.getName());
        bookNumber.setText(myItem.getNumber());
        bookPos.setText(myItem.getPosition());

        return convertView;
    }
}


일단 커스텀 어댑터는 BaseAdapter를 상속해야한다. 그 후 데이터들을 한꺼번에 담을 list를 생성해주고 생성자를 생성, 사이즈 설정해주기, 데이터 정보 가져오기, id 값 가져오기를 설정해주자.
이제 getView로 리스트뷰와 연결하는 메소드를 만들어준다. inflater로 xml로 만들어진 view를 객체화 시켜주고 convertView로 가져온 데이터들을 list_ui의 데이터들에 세팅시켜주고 convertView를 반환해준다.

이제 기본 어댑터 대신 CustomAdapter를 불러와 쓰면 된다.


댓글