[Android] CustomAdapter

728x90
CustomAdapter

- AdapterView의 항목을 자유롭게 디자인해서 사용할 때에는 SimpleAdapter만으로도 충분함

- 하지만 AdapterView 자체를 커스터마이징하여 특별한 기능을 부여하고 싶을 때에는 Adapter 클래스를 구현하면 된다. 

 

BaseAdapter

- BaseAdapter를 상속받아 다음 메서드를 구현하면 된다.

- getCount : AdapterView를 통해 보여줄 항목의 개수를 반환 -> 반드시 구현해야 함

- getView : AdapterVeiw를 통해 보여줄 항목의 View를 반환 -> 반드시 구현해야 함

 

package kr.co.customadapter;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import kr.co.customadapter.databinding.ActivityMainBinding;
import kr.co.customadapter.databinding.RowBinding;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding activityMainBinding;

    String[] data1 = {
            "데이터1", "데이터2", "데이터3", "데이터4", "데이터5"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(activityMainBinding.getRoot());

        //어댑터를 적용한다
        CustomAdapter adapter1 = new CustomAdapter();
        activityMainBinding.list1.setAdapter(adapter1);
    }

    //baseadapter를 상속받은 클래스
    class CustomAdapter extends BaseAdapter{

        //어댑터뷰를 통해 보여줄 항목의 개수를 결정함
        @Override
        public int getCount() {
            return data1.length;
        }

        //생성된 항목 뷰를 반환하는 목적으로 사용함
        //터치한게 어떤 항목인지 알기 위한 것으로 사용하는데, 우리가 그냥 받아올 수 있기 때문에 이거를 크게 사용하지는 않음
        @Override
        public Object getItem(int i) {
            return null;
        }

        //생성된 항목 뷰의 아이디를 반환하는 목적.
        //몇 번째 인지 포지션 값을 얻어서 이벤트 처리를 할 수 있기 때문에 잘 쓰지 않음
        @Override
        public long getItemId(int i) {
            return 0;
        }

        //항목 하나를 구성하기 위해 호출되는 메서드
        //첫 번째 매개변수 : 위치
        //두 번째 매개변수 : 재사용 가능한 항목 뷰가 전달됨.
        //               메모리 절약을 위해 눈에 보이는 만큼만 항목을 만드는데 스크롤을 하게 되면 스크롤해서 안보이게 된 항목을 스르롤해서 보여야하는 항목으로 반환하여 재사용
        //               -> 사라진애를 가지고 있다가 다음번에 호출할 때 매개변수로 전달해 주게 된다
        //               -> 즉, 메모리상의 한 공간을 만들어 리스트 어댑터뷰를 구성 했을 때 항목이 사라져서 안보이게되면 가지고 있다가 홏ㄹ될 때 공간에 들어오는 뷰가 있다면
        //                  담아 놨던 애를 재사용함. 만약 재사용한 뷰가 없다면 null이 들어옴 (null이 들어오면 재사용 가능한 뷰가 없기 때문에 계속해서 생성을 하면 됨.
        //세 번째 매개변수 : 여기서 만든 뷰를 어디에 배치할 것인가를 정함
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {

            RowBinding rowBinding = null;

            //재사용 가능한 항목 뷰가 없다면
            //최초에 리스트가 만들어 질 때 (ex 화면에서 보이는 리스트가 7개라면 7번 호출)
            if(view == null){
                rowBinding = RowBinding.inflate(getLayoutInflater());
                view = rowBinding.getRoot();
                //바인딩 객체를 뷰에 저장한다.
                view.setTag(rowBinding);
            } else {
                // 재사용 가능한 뷰가 있다면
                // 이 뷰를 만들 때 사용했던 바인딩 객체를 추출
                rowBinding = (RowBinding) view.getTag();
            }

            //값 세팅
            rowBinding.rowText1.setText(data1[i]);

            return view;
        }
    }
}

 

 

버튼을 눌렀을 때 이벤트는 각각 처리 되어야한다.

 

package kr.co.customadapter;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import kr.co.customadapter.databinding.ActivityMainBinding;
import kr.co.customadapter.databinding.RowBinding;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding activityMainBinding;

    String[] data1 = {
            "데이터1", "데이터2", "데이터3", "데이터4", "데이터5"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(activityMainBinding.getRoot());

        //어댑터를 적용한다
        CustomAdapter adapter1 = new CustomAdapter();
        activityMainBinding.list1.setAdapter(adapter1);
    }

    //baseadapter를 상속받은 클래스
    class CustomAdapter extends BaseAdapter{

        RowButtonClickListener1 listener1 = new RowButtonClickListener1();


        //어댑터뷰를 통해 보여줄 항목의 개수를 결정함
        @Override
        public int getCount() {
            return data1.length;
        }

        //생성된 항목 뷰를 반환하는 목적으로 사용함
        //터치한게 어떤 항목인지 알기 위한 것으로 사용하는데, 우리가 그냥 받아올 수 있기 때문에 이거를 크게 사용하지는 않음
        @Override
        public Object getItem(int i) {
            return null;
        }

        //생성된 항목 뷰의 아이디를 반환하는 목적.
        //몇 번째 인지 포지션 값을 얻어서 이벤트 처리를 할 수 있기 때문에 잘 쓰지 않음
        @Override
        public long getItemId(int i) {
            return 0;
        }

        //항목 하나를 구성하기 위해 호출되는 메서드
        //첫 번째 매개변수 : 위치
        //두 번째 매개변수 : 재사용 가능한 항목 뷰가 전달됨.
        //               메모리 절약을 위해 눈에 보이는 만큼만 항목을 만드는데 스크롤을 하게 되면 스크롤해서 안보이게 된 항목을 스르롤해서 보여야하는 항목으로 반환하여 재사용
        //               -> 사라진애를 가지고 있다가 다음번에 호출할 때 매개변수로 전달해 주게 된다
        //               -> 즉, 메모리상의 한 공간을 만들어 리스트 어댑터뷰를 구성 했을 때 항목이 사라져서 안보이게되면 가지고 있다가 홏ㄹ될 때 공간에 들어오는 뷰가 있다면
        //                  담아 놨던 애를 재사용함. 만약 재사용한 뷰가 없다면 null이 들어옴 (null이 들어오면 재사용 가능한 뷰가 없기 때문에 계속해서 생성을 하면 됨.
        //세 번째 매개변수 : 여기서 만든 뷰를 어디에 배치할 것인가를 정함
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {

            RowBinding rowBinding = null;

            //재사용 가능한 항목 뷰가 없다면
            //최초에 리스트가 만들어 질 때 (ex 화면에서 보이는 리스트가 7개라면 7번 호출)
            if(view == null){
                rowBinding = RowBinding.inflate(getLayoutInflater());
                view = rowBinding.getRoot();
                //바인딩 객체를 뷰에 저장한다.
                view.setTag(rowBinding);
            } else {
                // 재사용 가능한 뷰가 있다면
                // 이 뷰를 만들 때 사용했던 바인딩 객체를 추출
                rowBinding = (RowBinding) view.getTag();
            }

            //값 세팅
            rowBinding.rowText1.setText(data1[i]);

            //버튼에 현재 위치값 저장
            rowBinding.rowButton1.setTag(i);
            rowBinding.rowButton2.setTag(i);

            //리스너를 생성해서 담는다
            //이미 몇번쨰 항목인지 알 수 있어 여러개 만들지 않아도 되기 때문에 하나만 사용
            rowBinding.rowButton1.setOnClickListener(listener1);
            rowBinding.rowButton2.setOnClickListener(listener1);

            return view;
        }
    }

    //항목 뷰가 가지고 있는 버튼을 눌렀을 때
    class RowButtonClickListener1 implements View.OnClickListener {

        @Override
        public void onClick(View view) {
            //항목 뷰 안의 버튼 2개를 구분해야한다
            //사용자가 누른 버튼의 id를 추춘
            int id = view.getId();

            //항목 위치값을 가져온다
            int position = (int) view.getTag();

            //버튼을 누르면 해당 주소값이 변수 view에 들어오기 떄문에
            //위의 i값(위치값)을 저장 해 두면 몇 번째 항목의 버튼인지 파악할 수 있음
            //R.id.rowButton1
            // switch 대신 if-else 사용
            if (id == R.id.rowButton1) {
                // rowButton1을 눌렀을 때의 처리
                activityMainBinding.textView.setText("첫 번째 버튼을 누름 --> "+position);

            } else if (id == R.id.rowButton2) {
                // rowButton2를 눌렀을 때의 처리
                activityMainBinding.textView.setText("두 번째 버튼을 누름 --> "+position);

            }
        }
    }
}

728x90

'안드로이드 스튜디오' 카테고리의 다른 글

[Android] Custom ListView  (0) 2026.03.02
[Android] ListView  (0) 2026.03.02
[Android] 라이브러리 버전 수정 방법  (0) 2026.02.25
[Android] ToggleButton  (0) 2026.02.02
[Android] ImageView  (1) 2026.02.02