본문 바로가기

TIL

[TIL] Adapter 활용한 ListView, GridView

[오늘 배운 내용]

-1- Adapter, AdapterView

  • 어댑터(Adapter)란? 데이터를 받아서 관리하고 어댑터 뷰에 출력할 수 있는 형태로 데이터를 제공하는 객체이다
  • 어댑터가 데이터를 가공해서 제공하면 어댑터 뷰는 그 데이터를 출력하는 역할을 한다.
  • 어댑터를 사용하는 이유
    • 많은 정보를 효율적으로 처리하기 위해서 View에 바로 데이터를 저장하지 않고, 어댑터 객체를 이용.
    • 대표적인 어댑터 뷰의 서브 클래스 : ListView, GridView 등
  • 어댑터 뷰는 어떻게 데이터 항목을 표시할까?
    • 어댑터 뷰가 어댑터를 사용하기 위해서는 먼저 데이터 원본이 어댑터에 설정되어야 하고, 어댑터 뷰에는 어댑터가 설정되어야 한다.
    • 어댑터 뷰는 어댑터의 getView() 란 메소드를 통해서 화면에 실제로 표시할 항목뷰를 얻고, 이를 화면에 표시한다.
  • 어댑터의 종류
    • BaseAdapter
      • 어댑터 클래스의 공통 구현
    • ArrayAdapter
      • 객체 배열이나 리소스에 정의된 배열로부터 데이터를 공급받음
    • CursorAdapter
      • 데이터베이스로부터 데이터를 공급받음
    • SimpleAdapter
      • 데이터를 Map( Key, Value )의 리스트로 정리
      • 데이터를 xml 파일에 정의된 뷰에 대응시키는 어댑터
  • ListView, Adapt 예시
    • XML
    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="80dp"
        android:layout_marginBottom="100dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ListView
            android:id="@+id/item_listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingStart="5dp" />
    </LinearLayout>
    • 메인kt
class ListView_Test_Activity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_list_view_test)

        var brand: Array<String> =
            arrayOf("농심", "오뚜기", "롯데", "진로", "CJ", "오리온", "냠양", "풀무원", "하림", "동원", "삼립", "삼양")

        val brandList = findViewById<ListView>(R.id.item_listView)

        val adapter = ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, brand)

        brandList.adapter = adapter
    }
}

ListVIew

 

 

 

 


  • Grid View, Adapt 예시
    • XML
<GridView
        android:id="@+id/gridview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:columnWidth="100dp"
        android:numColumns="auto_fit"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:stretchMode="columnWidth"
        android:gravity="center"

        android:layout_marginTop="80dp"
        android:layout_marginBottom="150dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

 

 

 

    • 메인.kt + ImageAdapterClass
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val grieView_BrandList = findViewById<GridView>(R.id.gridview)

        grieView_BrandList.adapter = ImageAdapter()
    }
}

 

 

  • ImageAdapterClass
    • 아이템이 들어갈 brandIds 데이터를 상수로 먼저 선언해둔 뒤 BaseAdapt()를 상속받아서 ImageAdapter를 만들어 보자
import android.view.View
import android.view.ViewGroup
import android.widget.AbsListView
import android.widget.BaseAdapter
import android.widget.ImageView

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

    override fun getItem(position: Int): Any {
        return brandIds[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(brandIds.get(position))
        return imageView
    }


    private val brandIds = arrayOf( 이미지 리소스 파일 )
}
  • ImageAdapter 클래스
    • getCount() = 아이템의 갯수 작성코드
    • getItem(position:Int) = 아이템의 위치, // 파라미터인 position도 인덱스와 같이 0부터 시작한다.
    • getItemId(position: Int) =  포지션에 해당하는 아이템의 Id설정
    • getView(position:Int, convertView: View? parent:ViewGroup):View 
      • 첫번째 파라미터로 주어진 위치의 항목 뷰를 반환하는 것으로 position 위치의 Image Resource 를  ImageVIew에 설정하고, 설정된 ImageVIew 객체를 그리드 뷰의 항목뷰로 반환한다.
    • convertView = 이전에 생성된 항목뷰로 가능하다면 재사용할 이전 뷰를 의미한다 만약 이전에 만들어진 View가 있다면, 재사용하고 이전에 만들어진 VIew가 없다면 else로 항목에 맞는 ImageView 생성
      • else {imageView = convertView as ImageView} convertView= null 이면 width200,height200의 centerCrop의 이미지 타입이 지정된 top,bottom,start,end모두 8의 패딩을 가지고 있는 레이아웃을 생성한다

gridVIew

 

 

 

 

 


 

[오늘 복습한 내용]

1. 문자열 정렬하기

 

  • 나의 풀이 코드

 

 


[오류,에러 등등]

1. viewBinding코드 빼 먹는 실수

  • Unable to start activity ComponentInfo
  • 간단한 viewBinding을 하루 배웠다고 머릿속에 있는 코드로 작성 하려다가 오류가 났다.

 

// 수정전 코드
class MainActivity : AppCompatActivity() {
    private lateinit var viewBinding: ActivityMainBinding
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityMainBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)
    }
}

// 수정 후 코드
class MainActivity : AppCompatActivity() {
    private lateinit var viewBinding: ActivityMainBinding
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)
    }
}

onCreate 아래에 viewBinding = 을 빼먹어서 초기화가 안되었다고 한다;;;; 앞으로 viewBinding 코드는 절대 못 잊을 것 같다.

 

 


[느낀 점]

1. 이미 충분히 어려운데 점점 더 어려워 지고 있으나 재미는 있다

 

2. 학습을 하면서 새로운 함수를 접하게 되면 해당 함수의 파라미터 구성요소를 한번씩 확인하면 좋을 것 같다

 

3. 다른 사람들이 작성한 코드를 보면 도움이 많이 되는 것 같다. 복잡하더라도 한번씩 시도해봐야겠다.

 

 

 


[Reference]

 

 

 

https://todaycode.tistory.com/131

https://no1msh1217.tistory.com/17

https://sharp57dev.tistory.com/23

https://0391kjy.tistory.com/53

https://developer.android.com/reference/android/widget/Adapter#getView(int,%20android.view.View,%20android.view.ViewGroup)