본문 바로가기
Android

안드로이드 스튜디오, JAVA] 커스텀 리스트뷰(ListView) 만들기

by 김마리님 2020. 7. 22.

https://itstudy-mary.tistory.com/206

 

안드로이드 스튜디오, JAVA] 기본 리스트뷰(ListView) 만들기

기본적으로 안드로이드는 ListView를 기본적으로 제공한다. 리스트뷰가 무엇이냐면, 보면 Aㅏ 한다. 결과 : 구현법은 간단하다. 띄울 액티비티 xml 파일에 ListView 속성을 만든다. activity_main.xml

itstudy-mary.tistory.com

 

지난 포스팅에 이어서 커스텀 리스트뷰를 만든다.

결과 먼저 보자.

 

결과 화면 :

 

어댑터에서 담당했던걸 가만 생각해보면,

만들었던 데이터를 받아 뷰에 출력해주었다.

그럼 먼저 출력받을 뷰 한칸을 제작한다.

 

item.xml

<?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="100dp">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="99dp"
        android:text="^-^"
        android:textSize="30sp"
        android:textStyle="bold"
        android:gravity="center"/>

    <View
        android:layout_below="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#505050"/>
    
</RelativeLayout>

(진짜 한칸임. 어차피 바뀌니까 좋아하는거 씁시다.)

 

다음 이 뷰를 사용해줄 어댑터를 제작한다.

 

새로운 클래스를 제작한다.

 

SingleAdapter. java

package com.mary.movieapp;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

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

public class SingleAdapter extends BaseAdapter {
    private static final String TAG = "SingleAdapter";

    private List<String> items=new ArrayList<>();

    public void addItems(List<String> items){
        this.items=items;
    }

    @Override
    public int getCount() { //최초에 화면의 갯수를 설정함
        Log.d(TAG, "getCount: ");
        return items.size();
    }

    @Override
    public Object getItem(int position) { //아이템이 클릭될 때 아이템의 데이터를 도출
        Log.d(TAG, "getItem: ");
        return items.get(position);
    }

    @Override
    public long getItemId(int position) { //필수 아님
        Log.d(TAG, "getItemId: ");
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.d(TAG, "getView: "+position);
        LayoutInflater inflater=LayoutInflater.from(parent.getContext());
        View itemView=inflater.inflate(R.layout.item,parent,false);
        TextView tv=itemView.findViewById(R.id.tv_title);
        tv.setText(getItem(position).toString());
        return itemView;
    }
}

 

 

클래스가 Adapter의 역할을 하기 위해서는 BaseAdapter을 반드시 상속받아야 한다. 

BaseAdapter은 추상클래스이기 때문에,

반드시 사용해야할 매서드가 존재한다(이걸 모르겠으면 객체지향 언어부터 다시 보고 오자.).

BaseAdapter은 getCount, getItem, getItemId, getView 네 개의 매서드를 지정한다.

그 전에, 먼저 메인 액티비티에서 리스트 내의 값을 지정할 경우, 이 값을 넣어줄 함수가 필요한데, 이 함수가 addItems 이다(사실 foreach문을 돌려가면서 하나하나씩 add해야하는데 그러려니 합시다.).

 

앞의 세 함수는 옆에 달아둔 주석대로, 설명이 그대로다. 

대미는 View이다. 얘가 그거다.. 그거... 뷰에 넣어줄 함수...

먼저 메모리에 뜨기 위한 Inflater을 먼저 만든다. 이 때, 이 인플레이터가 어디 컨텍스트에 뜰건지도 from 속성을 통해 지정한다.

이제, 우리가 맨 앞에 만들었던 item.xml을 호출해서 View로 그려지게끔 한다. 그것이 inflate 속성이다.

(R은 안드로이드의 전체 컨텍스트를 총괄하는 파일이다. 따라서 레이아웃도 전부 올라가있다.)

그러니까, item의 전체 레이아웃을 불러와서, 올릴 뷰그룹을 결정한다(여기서는 부모그룹, 메인이겠다.). attachToRoot는.. false를 한다. 왜냐면 true를 하면 최상위 루트의 자식이 되고, false를 하면 그냥 그림을 그리는걸로 끝나기 때문이다.

우리는 그림만 그릴거니까 ^^ ...

이제 item.xml의 텍스트를 찾아서 우리가 받아온 items의 이름으로 갈아치우기만 하면 어댑터는 끝난다.

 

마지막으로, 이 어댑터를 메인에서 호출하면,

 

MainActivity. java

package com.mary.movieapp;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.opengl.EGLExt;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "Main_Activity";
    private Context mContext=MainActivity.this;
    private ListView listView;
    private SingleAdapter adapter;

    List<String> items = Arrays.asList(
            "히어로즈","24시","로스트","로스트룸","빅뱅이론","프렌즈","덱스터","글리","히어로즈","24시","로스트","로스트룸","빅뱅이론","프렌즈","덱스터","글리"
    );

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

        adapter=new SingleAdapter();
        listView=findViewById(R.id.list_view);

        adapter.addItems(items);

        listView.setAdapter(adapter);



    }
}

 

우리가 클래스 상속을 받으면서 받아온 네 개의 매서드의 역할은, Logcat으로 디버그로그를 찍어보면 역할을 알 수 있다

 

움짤로 보다시피, 뷰가 새로운 값을 도출할때마다 뜨는 걸 볼 수 있다. 뷰가 완성되면, getItem 함수가 만들어진 값을 읽어내는 것도 확인할 수 있다.

getCount는 딱 두번 뜨는데, 

1. 처음 생성될 때

2. 내릴 때

딱 두번만 도출된다.

 

 

반응형