1. 어댑터 뷰
: 여러개의 항목을 다양한 형식(이미지뷰 + 텍스트뷰 등)으로 나열하고 선택할 수 있는 기능을 제공하는 뷰
// 하나 만들어두고 재사용하는...st
- 표시할 항목 데이터를 직접 관리하지 않고, 어댑터라는 객체로부터 공급받음
| 어댑터 뷰 | <--> | 어댑터 | 데이터 원본 |
| 1) 리스트 뷰 : 항목을 수직으로 나열 2) 그리드 뷰 : 항목을 격자 형태로 나열 |
- 객체 배열 - 리소스 - 데이터베이스 - 컨텐츠 프로바이더 |
1) 어댑터 : 데이터를 관리하며, 데이터 원본과 어댑터뷰 사이의 중계 역할 수행
= 어댑터에 정의된 인터페이스를 바탕으로 필요한 정보를 요청해,
항목 뷰를 화면에 표시하거나 선택된 항목뷰를 처리함
(1) 어댑터뷰가 어댑터를 사용하기 위해서
ㄱ. 데이터 원본이 어댑터에 설정되어야 함
ㄴ. 어댑터뷰에는 어댑터가 설정되어야 함
== 어댑터가 원본을 가지고 있어야 하고, 어댑터뷰는 그 어댑터와 연결되어있어야 함
(2) 어댑터뷰는 항목을 표시하기 위해 먼저 표시할 항목의 총 개수를 알아야 함
- 어댑터 뷰는 어댑터의 getCount() 메소드를 통해 현재 어댑터가 관리하는 데이터 항목의 총 개수를 반환
(3) 어댑터 뷰가 어댑터의 getView() 메소드를 통해 화면에 실제로 표시할 항목 뷰를 얻고 화면에 표시
- 사용자가 어댑터뷰의 특정 위치의 항목을 선택했을 때,
어댑터뷰는 선택된 항목, 항목의 ID, 항목의 뷰를
어댑터의 getItem(), getItemId(), getView() 메소드를 통해 얻어와서
이를 항목선택 이벤트 처리기에 넘김

2) 어댑터 종류
| (1) BaseAdapter | - 어댑터 클래스의 공통 구현 - 사용자 정의 어댑터 구현 시 사용 |
|
| (2) ArrayAdapter | - 객체 배열이나 리소스에 정의된 배열로부터 데이터를 공급받음 | |
| (3) CursorAdapter | - 데이터베이스로부터 데이터를 공급받음 | |
| (4) SimpleAdapter | - 데이터를 Map(키, 값)의 리스트로 관리 - 데이터를 XML 파일에 정의된 뷰에 대응시키는 어댑터 |

2. 리스트 뷰 (ListView)
: 어댑터 뷰의 대표 위젯. 복수 개의 항목을 수직으로 표시
- 리스트 뷰 설정 절차
(1) 프로젝트 생성 (ex. SimpleListViewTest 프로젝트)
(2) 메인화면 레이아웃에 ListView 위젯 정의(XML 코드)
- 메인 화면 레이아웃 (ex. 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>
(3) 어댑터 객체 생성 (Kotlin 코드)
- 데이터 원본이 배열인 경우에 ArrayAdapter 객체 사용
- ArrayAdapter 생성자 => ArrayAdapter(Context context, int resource, int textViewResourceId, T[ ] objects)
- context : 현재 콘텍스트
- resource : 항목으로 표시될 텍스트 뷰의 리소스 ID
| 리소스 ID | 설명 | |
| android.R.layout.simple_list_item_1 | 하나의 텍스트 뷰로 구성된 레이아웃 | |
| android.R.layout.simple_list_item_2 | 두 개의 텍스트 뷰로 구성된 레이아웃 | |
| android.R.layout.simple_list_item_checked | 오른쪽에 체크 표시가 나타남 | |
| android.R.layout.simple_list_item_single_choice | 오른쪽에 라디오 버튼이 나타남 | |
| android.R.layout.simple_list_item_multiple_choice | 오른쪽에 체크 버튼이 나타남 |
- objects : 어댑터로 공급될 데이터 원본으로 단순 배열
//string 배열을 이용한 ArrayAdapter 객체 생성 예제
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)
}
}
(4) ListView 객체에 어댑터 연결 (Kotlin 코드)
- 현 화면 레이아웃(ex. activity_main.xml)에 정의된 뷰 중에서 id가 listView인 ListView 객체를 ViewBinding 통해 얻어옴
- 얻어온 ListView 객체에 생성된 어댑터 객체(ex. ArrayAdapter 객체 - adapter)를 연결함
//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
// }
//}
3. 그리드 뷰
: 2차원 스크롤 가능한 그리드에 항목을 표시
1) 그리드 뷰 설정 절차
(1) 새 프로젝트 생성 (ex. SimpleGridViewTest)
(2) 메인화면 레이아웃에 GridView 위젯 정의 (xml 코드)
- 메인화면 레이아웃(ex. activity_main.xml) 에 GridView 위젯 추가 (추가? 대체? @@@@)
- xml 레이아웃 파일에 정의된 GridView 위젯을 kotlin 코드에서 참조하기 위해 id속성을 정의
<?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" | 열 내부의 여백을 폭에 맞게 채움 |
(3) ArrayAdapter 객체를 생성하고 GridView 객체에 연결 (Kotlin 코드)
1. ArrayAdapter 객체를 생성
2. id를 바탕으로 메인화면 레이아웃(activity_main.xml)에 정의된 GridView 객체 로딩
3. 생성된 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, R.layout.simple_list_item_1, items)
// 어댑터를 GridView 객체에 연결
binding.gridview.adapter = adapter
}
}
2) 이미지 그리드 뷰
(1) 프로젝트 생성 (ex. ImageGridViewTest)
(2) 메인화면 레이아웃에 GridView 위젯 정의 (xml 코드)
- 메인화면 레이아웃(activity_main.xml)에 GridView 위젯 추가
- xml 레이아웃 파일에 정의된 GridView 위젯을 java코드에서 참조하기 위해 id속성을 정의
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<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" />
</androidx.constraintlayout.widget.ConstraintLayout>
(3) 어댑터 정의 (Kotlin 코드)
- 그리드 뷰의 항목으로 간단한 텍스트가 아닌 이미지를 사용하려는 경우
=> 그리드뷰의 항목으로 이미지를 공급하는 ImageAdapter 를 BaseAdapter로부터 파생해 정의
//MainActivity 에 추가하는듯
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)
//레이아웃이 200*200짜리를 만들고
imageView.layoutParams = AbsListView.LayoutParams(200, 200)
//
imageView.scaleType = ImageView.ScaleType.CENTER_CROP
//
imageView.setPadding(8, 8, 8, 8)
} else {
imageView = convertView as ImageView
}
//getView를 할 때, 몇 번째 포지션인지. 그 포지션에 해당하는 사진을 여기 넣겠다는 뜻
imageView.setImageResource(mThumbIds.get(position))
//set한 뷰 자체를 리턴
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
)
}
//ImageAdapter가 관리하는 데이터는 편의상 ImageAdapter 내부에 Image 리소스 ID 의 배열로 설정(편의상)
| //BaseAdapter의 getCount(), getItem(), getItemId(), getView() 메소드를 재정의 | |
| - getCount | 항목의 총 개수를 반환하기 위해 mThumbIds 배열의 크기를 반환 |
| - getItem() | 특정 위치의 항목 반환 위해 mThumbIds 배열의 지정된 위치의 항목을 반환 |
| - getItemId() | 특정 위치의 항목 아이디를 반환 (여기서는 배열의 위치(순서)를 항목의 아이디로 간주함) |
| - getView() | 첫 번째 파라미터로 주어진 위치의 항목 뷰를 반환 = mThumbIds 배열의 position 위치에 있는 이미지 리소스를 ImageView 의 이미지로 설정하고, 이 설정된 ImageView 객체를 그리드 뷰의 항목뷰로 반환 - getView() 메소드의 두번째 파라미터인 convertView는 이전에 생성된 항목뷰(여기선 ImageView)를 의미 1) 해당 위치의 항목뷰가 처음 만들어지는 경우 -> 새 이미지뷰 객체 만들고 크기, 스케일타입, 패딩 설정 2) 이전에 이미 만들어진 경우 -> 이를 재사용 - 이미지뷰의 scaleType은 원본 이미지를 이미지 뷰에 맞게 확대 및 축소시킬 때, 어떻게 처리할지를 지정 - CENTER_CROP : 종횡비를 유지하여 스케일링하며 뷰의 크기 이상으로 채우게 됨을 의미 = 이미지 일부가 잘릴 수 있음 |
(4) 어댑터를 생성하고 GridView 객체에 연결 (Kotlin 코드) + 항목 클릭 이벤트 처리
- ImageAdapter 객체를 생성하고 이를 GridView 객체에 연결하기
- GridView 객체에 연결한 ImageAdapter 객체가 클릭될 때 호출될 내용 추가
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()
}
}
}
// onItemClickListener의 파라미터들
- parent : 클릭 이벤트가 발생된 AdapterView
- view : 실제 클릭 된 AdapterView 안의 View
- position : 어댑터 내에서 클릭 된 항목/뷰의 위치
- id : 클릭 된 항목의 id
//adapterview들이 onclicklistener를 다 갖고 있음... 클릭되면 콜백값으로 parent랑 view, position, id가 넘어오게 됨.
(그 중에서 position만 필요하면 그것만 밑에서 사용해도 됨.)
'Android Studio' 카테고리의 다른 글
| [Android 앱개발 숙련] 프래그먼트 Fragment - 개념 (# 추가하기) (0) | 2024.04.11 |
|---|---|
| [Android 앱개발 숙련] RecyclerView 리사이클러 뷰 (# 추가하기) (0) | 2024.04.11 |
| [Android 앱개발 숙련] 뷰 바인딩 - 개념, 설정방법 (# 추가하기) (0) | 2024.04.09 |
| 안드로이드 스튜디오 TTS 관련 코드 (0) | 2024.04.08 |
| [Android 앱개발 입문] 액티비티 생명주기 (# 추가하기) (0) | 2024.03.21 |