티스토리 뷰
앱개발 숙련 1주차 정리 - 1
뷰 바인딩
gradle 설정
android{
...
buildFeatures{
viewBinding = true
}
}
android studio 버전이 4.0이상이면 해당 구문을 그래들 파일에 추가한다.
Activity 설정
class MainActivity : AppCompatActivity(){
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
코드 3줄로 액티비티에서 바인딩 설정이 가능하다.
바인딩 클래스의 이름은 레이아웃 파일의 이름에 따라 결정된다.
바인딩 사용
binding.textView.text = "Hello"
binding.뷰 아이디로 레이아웃의 특정 뷰에 접근할 수 있다.
어댑터 뷰
어댑터 뷰란?
어댑터 뷰는 여러 개의 항목을 나열하는데 쓰이는 뷰이다.
어댑터 뷰는 표시할 항목 데이터를 직접 관리하지 않고,
어댑터라는 객체로부터 공급받는다.
어댑터란?
데이터와 어댑터 뷰 사이에서 데이터를 관리하는 역할이다.
사용자가 어댑터뷰의 특정 항목을 선택하였을 때,
어댑터뷰는 선택된 항목의 정보를 어댑터의 메소드를 통해 얻어와서
이를 항목선택 이벤트 처리기에 넘겨준다.
1. 데이터 원본을 어댑터에 설정하고, 어댑터뷰에는 어댑터를 설정한다.
2. 어댑터의 getCount()메소드로 데이터 항목의 총 개수를 반환한다.
3. 어댑터의 getView()란 메소드를 통해 화면에
실제로 표시할 항목뷰를 얻고, 이를 화면에 표시합니다.
위와 같은 과정을 거쳐 어댑터뷰는 데이터를 화면에 표시한다.
어댑터 종류
1) BaseAdapter
- 어댑터 클래스의 공통 구현
- 사용자 정의 어댑터 구현 시 사용
*2) ArrayAdapter
- 객체 배열이나 리소스에 정의된 배열로부터 데이터를 공급받음
3) CursorAdapter
- 데이터베이스로부터 데이터를 공급받음
4) SimpleAdapter
- 데이터를 Map(키,값)의 리스트로 관리
- 데이터를 XML파일에 정의된 뷰에 대응시키는 어댑터
2~4번 어댑터는 기본 어댑터를 확장한 클래스에 해당한다.
리스트뷰 만들기
어댑터에는 리소스가 존재한다.
// 데이터 설정
val items = arrayOf<String?>("item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8")
// 어댑터 설정
val adapter = ArrayAdapter(this, R.layout.simple_list_item_1, items)
// 리스트뷰에 어댑터 연결
binding.listview.adapter = adapter
리스트뷰의 어댑터를 초기화하는 구문이다.
리스트뷰는 여러 개의 항목을 수직으로 배치한다.
그리드뷰 만들기
<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" />
원하는 형식으로 그리드뷰를 출력하려면
그리드뷰 항목의 폭과 배치속성을 지정해줘야한다.
그리드뷰의 어댑터 설정 방법은 리스트뷰와 동일하다.
그리드뷰는 격자 형태로 항목을 출력한다.
RecyclerView
효율성
ListView는 스크롤 시에 위쪽 아이템은 삭제되고,
맨 아래의 아이템은 생성 되는 동작을 반복한다.
계속해서 삭제와 생성을 반복하기에 성능에 좋지 않다.
이러한 문제점을 해결하기 위해 RecyclerView를 쓴다.
RecyclerView는 스크롤 시에 위쪽 아이템을 아래로 이동시켜 재사용한다.
구성요소
1) Adapter
- Adapter는 데이터 테이블을 목록 형태로 보여주기 위해 사용된다.
- 즉 데이터와 RecyclerView 사이의 통신을 위한 연결체에 해당한다.
2) ViewHolder
- ViewHolde는 화면에 표시될 데이터나 아이템들을 저장한다.
- 스크롤로 인해 위로 올라간 View를 재활용하기 위해서 ViewHolder로 해당 View를 기억한다.
RecyclerView 예제
데이터 준비
data class MyItem(val img:Int, val name:String, val code:String) {}
출력할 항목에 맞게 데이터 클래스를 작성해준다.
val dataList = mutableListOf<MyItem>()
dataList.add(MyItem(R.drawable.color1, "blue", "54A7D9"))
dataList.add(MyItem(R.drawable.color2, "yellow", "EDDC4A"))
dataList.add(MyItem(R.drawable.color3, "red", "D44A47"))
dataList.add(MyItem(R.drawable.color4, "red", "090707"))
리싸이클러뷰를 출력하는 액티비티 파일의 onCreate() 내에서
데이터리스트를 정의하고 데이터를 추가하는 구문을 작성해준다.
실제로 프로젝트 진행할 때는 서버에서 데이터를 받아오게 된다.
아이템 레이아웃
LinearLayout을 활용해 아이템 레이아웃을 만들어준다.
레이아웃의 정렬속성과 위젯의 가중치를 적절히 설정하여 원하는대로 배치시킨다.
어댑터 클래스 정의
class MyAdapter(val mItems: MutableList<MyItem>) : RecyclerView.Adapter<MyAdapter.Holder>() {
어댑터 클래스는 초기화한 데이터를 인자로 받아 RecylcerView의 어댑터 클래스를 상속한다.
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount(): Int {
return mItems.size
}
아이템의 정보를 받아오는 두 메소드는 반드시 오버라이딩을 진행해줘야 한다.
홀더 클래스 정의
inner class Holder(val binding: ItemBinding) : RecyclerView.ViewHolder(binding.root) {
val image = binding.imgItem
val name = binding.textItem1
val code = binding.textItem2
}
홀더 클래스를 어댑터 클래스의 내부 클래스로 정의한다.
홀더 클래스는 RecylcerView의 뷰홀더 클래스를 상속한다.
아이템 레이아웃의 바인딩을 인자로 받아 항목의 각 구성요소를 변수로 초기화한다.
뷰홀더 생성
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val binding = ItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return Holder(binding)
}
이 함수는 새로운 뷰홀더를 생성할 때 호출된다.
아이템 레이아웃을 인플레이트한 뒤 홀더 클래스를 반환한다.
뷰홀더 바인딩
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.itemView.setOnClickListener {
itemClick?.onClick(it, position)
}
holder.image.setImageResource(mItems[position].img)
holder.name.text = mItems[position].name
holder.code.text = mItems[position].code
}
해당 함수는 특정 위치의 데이터와 뷰홀더를 바인딩해 화면에 띄우는
역할을 하며 화면에 보이는 항목의 개수만큼 반복해서 호출된다.
어댑터가 아이템 뷰를 재사용할때마다 호출되는 함수이다.
클릭 이벤트 정의
특정 항목을 눌렀을 때 상세페이지 같은 거 띄우려면
클릭 이벤트를 정의해 해당 항목의 데이터를 넘겨줘야한다.
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.itemView.setOnClickListener {
// 여기서 정의
}
// 데이터 바인딩 구문
}
뷰홀더 바인딩 함수에서 클릭 이벤트를 정의해도 상관없으나
메인에서 정의하고 싶다면 메인액티비티와 어댑터 사이에서
통신할 수 있도록 인터페이스를 하나 정의해줘야 한다.
interface ItemClick {
fun onClick(view : View, position : Int)
}
인터페이스 내에는 onClick이라는 추상 메소드가 정의되어 있으며
어떤 항목을 클릭했는지 식별할 수 있도록 클릭된 항목의 뷰와 위치값을 인자로 받는다.
var itemClick : ItemClick? = null
초기값을 null로 가지는 ItemClick 인터페이스 타입의 변수를 선언해준다.
adapter.itemClick = object : MyAdapter.ItemClick {
override fun onClick(view: View, position: Int) {
val name: String = dataList[position].name
Toast.makeText(this@MainActivity," $name 선택!", Toast.LENGTH_SHORT).show()
}
}
메인의 onCreate()내에서 아이템 클릭 변수를 초기화한다.
itemClick을 어댑터 클래스의 ItemClick 인터페이스를 상속하는
오브젝트 타입으로 선언한 뒤, 해당 인터페이스의 onClick 메소드를 오버라이딩한다.
어댑터 설정
val adapter = MyAdapter(dataList)
binding.recyclerView.adapter = adapter
binding.recyclerView.layoutManager = LinearLayoutManager(this)
메인에서 리싸이클러뷰의 어댑터를 정의한 어댑터 클래스로 초기화한다.
레이아웃 매니저를 LinaerLayoutManager로 초기화해 아이템을 일렬로 배치하도록 한다.
실행결과
4개의 색상을 리싸이클러뷰로 출력해보았다.
각 항목은 색상이미지, 색상이름, 색상코드 데이터를 가진다.
'내일배움캠프 > Android 국비지원' 카테고리의 다른 글
TIL 45일차 (앱개발 숙련 1주차 정리 - 3) (0) | 2024.07.23 |
---|---|
TIL 44일차 (앱개발 숙련 1주차 정리 - 2) (1) | 2024.07.22 |
TIL 42일차 (챌린지반 3주차 세션 과제) (0) | 2024.07.12 |
TIL 41일차 (소수 찾기 - Kotiln | 코드카타 잠시 쉽니다) (0) | 2024.07.10 |
TIL 40일차 (가장 큰 수 - Kotlin | 챌린지반 3주차 세션 정리) (0) | 2024.07.09 |