ListView, GridView

낄낄몬스터·2024년 7월 9일
0

앱 개발 숙련

목록 보기
2/9

AdapterView

여러 개의 항목을 다양한 형식으로 나열하고 선택 할 수 있는 기능을 제공하는 뷰

표시할 항목 데이터를 직접 관리하지 않고,어댑터라는 객체로부터 공급 받음

ListView

복수 개의 항목을 수직으로 나열시키는 방식

리스트 뷰 설정 절차

메인 화면 레이아웃에 ListView위젯 정의

메인 화면 레이아웃 (예,activity_main.xml)에 ListView위젯을 추가, XML레이아웃 파일에 정의된 ListView 위젯을 Java코드에서 참조하기 위하여 id속성을 정의

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

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       />
</LinearLayout>

어댑터 객체 생성

데이터 원본이 배열인 경우에 ArrayAdapter 객체 사용

  • ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
    • context: 현재 컨텍스트

    • resource: 항목으로 표시될 텍스트 뷰의 리소스 ID

objects: 어댑터로 공급될 데이터 원본으로 단순 배열

ListView객체에 어댑터 연결

현재 화면 레이아웃(activity_main.xml)에 정의 된 뷰 중에서 id가 listView인 ListView 객체를 ViewBinding을 통해 얻어옴

얻어온 ListView객체에 생성된 어댑터 객체(예,ArrayAdapter객체-adapter)를 연결한다

e.g)

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 데이터 원본 준비
        val items = arrayOf<String?>("item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6",  "item7", "item8")

        //어댑터 준비 (배열 객체 이용, simple_list_item_1 리소스 사용
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)

        // 어댑터를 ListView 객체에 연결
        binding.listView.adapter = adapter

    }
}

GridView

항목을 격자 형태로 나열시키는 방식, 2차원 스크롤 가능한 그리드에 항목을 표시

그리드 뷰 설정 절차

  • Simple Grid View Test프로젝트 생성

  • 메인화면 레이아웃에 GridView위젯 정의 (XML코드)

  • ArrayAdapter객체를 생성하고 GridView객체에 연결 (Kotlin 코드)

메인화면 레이아웃에 GridView위젯 정의

메인화면 레이아웃(예,activity_main.xml)에 GridView 위젯을 추가, XML레이아웃 파일에 정의된 GridView 위젯을 Kotlin 코드에서 참조하기 위하여 id 속성을 정의

e.g)

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnWidth="100dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    />
  • android:columnWidth=“100dp” : 그리드 항목 하나의 폭을 100dp로 설정

  • android:numColumns=“auto_fit”: 열의 폭과 화면 폭을 바탕으로 자동 계산

  • android:verticalSpacing: 항목 간의 간격 설정

  • android:stretchMode=“columnWidth”: 열 내부의 여백을 폭에 맞게 채움

ArrayAdapter객체를 생성하고 GridView객체에 연결

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 데이터 원본 준비
        val items = arrayOf<String?>("item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6",  "item7", "item8")

        //어댑터 준비 (배열 객체 이용, simple_list_item_1 리소스 사용
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)

        // 어댑터를 GridView 객체에 연결
        binding.gridView.adapter = adapter

    }
}
  1. 간단한 리스트뷰 만들어 보기 예제와 마찬가지로, ArrayAdapter 객체를 생성

  2. id를 바탕으로 메인화면 레이아웃(activity_main.xml)에 정의된 GridView 객체 로딩

  3. 생성된 ArrayAdapter 객체를 GridView 객체에 연결

이미지 그리드 뷰 만들어보기

이미지 그리드 뷰 설정 절차

  • Image GridView Test 프로젝트 생성

  • 메인화면 레이아웃에 GridView위젯 정의(XML코드)

  • 어댑터 정의(Kotlin코드)

  • 어댑터를 생성하고 GridView객체에 연결(Kotlin코드)

메인 화면 레이아웃에 GridView위젯 정의

  • 메인화면 레이아웃(예,activity_main.xml)에 GridView위젯을 추가

  • XML레이아웃 파일에 정의된 GridView위젯을 Java코드에서 참조하기 위하여 id속성을정의

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnWidth="100dp"
    android:gravity="center"
    android:horizontalSpacing="10dp"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="10dp" />

Adapter정의

그리드 뷰의 항목으로 간단한 텍스트가 아닌 이미지를 사용하고자 하는 경우에는 그리드뷰의 항목으로 이미지를 공급하는 ImageAdapter를 BaseAdapter로부터 파생하여 정의

class ImageAdapter : BaseAdapter() {
    override fun getCount(): Int {
        return mThumbIds.size
    }

    override fun getItem(position: Int): Any {
        return mThumbIds[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val imageView: ImageView
        if (convertView == null) {
            imageView = ImageView(parent!!.context)
            imageView.layoutParams = AbsListView.LayoutParams(200, 200)
            imageView.scaleType = ImageView.ScaleType.CENTER_CROP
            imageView.setPadding(8, 8, 8, 8)
        } else {
            imageView = convertView as ImageView
        }

        imageView.setImageResource(mThumbIds.get(position))
        return imageView
    }

    private val mThumbIds = arrayOf<Int>(
        R.drawable.sample_2, R.drawable.sample_3,
        R.drawable.sample_4, R.drawable.sample_5,
        R.drawable.sample_6, R.drawable.sample_7,
        R.drawable.sample_0, R.drawable.sample_1,
        R.drawable.sample_2, R.drawable.sample_3,
        R.drawable.sample_4, R.drawable.sample_5,
        R.drawable.sample_6, R.drawable.sample_7,
        R.drawable.sample_0, R.drawable.sample_1,
        R.drawable.sample_2, R.drawable.sample_3,
        R.drawable.sample_4, R.drawable.sample_5,
        R.drawable.sample_6, R.drawable.sample_7
    )
}

app>res>drawable 하위에 이름이 sample_0에서 sample_7까지인 8개의 이미지 파일을 추가

  • ImageAdapter가 관리하는 데이터는 편의상 직접 ImageAdapter 내부에 Image 리소스 ID의 배열로 설정
  • BaseAdapter의 getCount()getItem()getItemId()getView() 메소드를 재정의
    • getCount()는 항목의 총 개수를 반환하기 위해 mThumbIds 배열의 크기를 반환
    • getItem()는 특정 위치의 항목을 반환하기 위해 mThumbIds 배열의 지정된 위치의 항목을 반환
    • getItemId()는 특정 위치의 항목 아이디를 반환하는 것인데, 여기서는 배열의 위치(순서)를 항목의 아이디로 간주
    • getView()는 getView 메소드는 첫번째 파라미터로 주어진 위치의 항목 뷰를 반환하는 것이므로, mThumbIds 배열의 position 위치에 있는 이미지 리소스를 ImageView의 이미지로 설정하고, 이 설정된 ImageView 객체를 그리드 뷰의 항목뷰로 반환
      • getView() 메소드의 두번째 파라미터인 convertView는 이전에 생성된 항목뷰 (여기서는 ImageView)를 의미. 만약 해당 위치의 항목뷰가 처음 만들어지는 경우라면, 새로운 이미지뷰 객체를 만들고 크기와 스케일타입, 패팅을 설정. 만약 이전에 이미 만들어진 것이라면, 이를 재사용
      • 이미지 뷰의 scaleType은 원본 이미지를 이미지 뷰에 맞게 확대 및 축소시킬 때, 어떻게 처리할 지를 지정하는 것인데, 여기서 CENTER_CROP은 종횡비를 유지하여 스케일링하며 뷰의 크기 이상으로 채우게 됨을 의미. 따라서 이미지 일부가 잘릴 수 있음

Adapter를 생성하고 GridView객체에 연결

그리드 뷰 설정의 마지막 단계는 ImageAdapter객체를 생성

이를 GridView객체에 연결 하는 것

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ImageAdapter 객체를 생성하고 GridView 객체에 연결
        binding.gridview.adapter = ImageAdapter()


    }
}

항목 클릭 이벤트 처리

AdapterView의 항목이 클릭 될 때, 호출되는 callbackmethod의 인터페이스

앞의 Image Grid View Test프로젝트 예제에서 항목 클릭 이벤트 처리코드 추가

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ImageAdapter 객체를 생성하고 GridView 객체에 연결
        binding.gridview.adapter = ImageAdapter()

        // 항목 클릭 이벤트 처리
        binding.gridview.setOnItemClickListener{ parent, view, position, id ->
            Toast.makeText(this@MainActivity,"" + (position + 1) + "번째 선택",           
                Toast.LENGTH_SHORT).show()
        }
    }
}

결과
업로드중..

어댑터(Adapter)

데이터를 관리하며 데이터 원본과 어댑터뷰(ListView, GridView) 사이의 중계 역할

어댑터뷰의 데이터 항목 표시 방법

어댑터뷰가 어댑터를 사용하기 위해서는 먼저 데이터 원본이 어댑터에 설정되어야 하고, 어댑터뷰에는 어댑터가 설정되어야 함

어댑터뷰는 항목을 표시하기 위해서 먼저 표시할 항목의 총 개수를 알 필요가 있음

이때, 어댑터 뷰는 어댑터의 getCount()란 메소드를 통해 현재 어댑터가 관리하는 데이터 항목의 총 개수를 반환

어댑터 뷰는 어댑터의 getView()란 메소드를 통해서 화면에 실제로 표시할 항목뷰를 얻고, 이를 화면에 표시

사용자가 어댑터뷰의 특정 위치의 항목을 선택하였을 때,
어댑터뷰는 선택된 항목, 항목ID, 항목뷰를
어댑터의 getItem(), getItemId(), getView() 메소드를 통해 얻어와서 이를 항목선택 이벤트 처리기에 넘겨줌

요약하면, 어댑터뷰는 어댑터에 정의된 인터페이스를 바탕으로 필요한 정보를 요청하여 항목뷰를 화면에 표시하거나 선택된 항목뷰를 처리

BaseAdapter

어댑터 클래스의 공통 구현, 사용자 정의 어댑터 구현 시 사용

ArrayAdapter

객체 배열이나 리소스에 정의된 배열로부터 데이터를 공급받음

CursorAdapter

데이터베이스로부터 데이터를 공급받음

SimpleAdapter

데이터를 Map(키,값)의 리스트로 관리, 데이터를 XML파일에 정의된 뷰에 대응시키는 어댑터

profile
음악을 사랑하는 예비 앱개발자

0개의 댓글