6분짜리 진정제입니다.
오늘은 새로운 팀원들과, 새로운 공부를 시작하는 첫 번째 날입니다.
다들 새롭게 뵙는 분들이라 기대 반 걱정 반입니다.
어쨌든 오늘 공부했던 내용들을 정리해보겠습니다.
처음 공부한 내용은 뷰 바인딩입니다.
뷰 바인딩은 뷰와 상호작용하는 코드를 더 쉽게 작성할 수 있게 하는 기능으로,
기존의 findViewById를 대체하며, Null과 타입에 대해서 안전합니다.
사용하기 전에 build.gradle에 빌드 옵션을을 설정해줘야 합니다.
android {
...
buildFeatures {
viewBinding = true
}
}
안드로이드 공식 문서에서 제공하는 사용 방법은 다음과 같습니다.
활동에 사용할 결합 클래스 인스턴스를 설정하려면 활동의 onCreate() 메서드에서 다음 단계를 따르세요.
1.생성된 결합 클래스에 포함된 정적 inflate() 메서드를 호출합니다. 그러면 활동에서 사용할 결합 클래스 인스턴스가 생성됩니다.
2.getRoot() 메서드를 호출하거나 Kotlin 속성 문법을 사용하여 루트 뷰 참조를 가져옵니다.
3.루트 뷰를 setContentView()에 전달하여 화면의 활성 뷰로 만듭니다.
위를 코드로 작성하면 아래와 같이 됩니다.
private lateinit var binding: ResultProfileBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
먼저, binding이라는 변수를 만들어, 액티비티나 레이아웃에 대한 binding 타입으로 만듭니다.
private lateinit var binding: ResultProfileBinding
그 후, inflate합니다. inflate와 layoutInflater는 내일 공부가 끝나면 추가적으로 더 공부해보겠습니다.
binding = ResultProfileBinding.inflate(layoutInflater)
마지막으로, view를 binding의 root. 즉, 최상단 뷰를 연결해주고, 이를 content view에 세팅합니다.
val view = binding.root
setContentView(view)
이렇게 하면, 기본적인 준비는 끝났습니다. 이제 findViewById 대신에 binding.뷰 로 쓰면 됩니다.
val textView = binding.tv_num
초기 과정만 기억하면, 간단하고 안정성 높게 만들어주는 좋은 방법입니다.
어제는 Adapter와 AdapterView에 대해 얘기했는데, 오늘은 RecyclerView와 그 Adapter에 대해 이야기해보겠습니다.
기본적인 방식 자체는 AdapterView와 비슷하지만, 가장 큰 차이점은 ViewHolder입니다.
RecyclerView는 그 뜻대로, 재활용해서 사용하는 뷰입니다. 이게 AdapterView 중 하나이므로,
요소들을 재활용하는 AdapterView라고 보시면 될 것 같습니다.
class MyAdapter(): RecyclerView.Adapter<MyAdapter.Holder>() {
// 홀더 클래스. 뷰 바인딩 해주기
inner class Holder(binding: LayoutRecyclerItemBinding): RecyclerView.ViewHolder(binding.root) {
var text = binding.tvItem
}
// 권장하는 방식 -> 인터페이스로 지정하고 이를 바깥에서 구현하는 걸 활용하는 방식을 자주 사용하고 권장된다
interface ItemClick {
fun onClick(view: View, position: Int)
}
var itemClick : ItemClick? = null
// View Holder를 만들고 전해주는 부분
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val binding = LayoutRecyclerItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return Holder(binding)
}
// 쓸 아이템 개수
override fun getItemCount(): Int {
return 3
}
//홀더에 뷰들을 설정하는 부분
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.text.text = "하하$position"
holder.text.setOnClickListener {
itemClick?.onClick(it, position)
}
}
}
먼저, RecyclerView의 Adapter 코드는 위와 같이 작성했습니다.
기존의 Adapter와 같이 ItemCount를 반환해 개수를 정합니다.
차이점인 ViewHolder라는 개념을 사용하는데, ViewHolder는 사용할 요소들을 잡아주고 있습니다.
여기서 ViewHolder는 Holder라는 내부 클래스를 활용합니다.
inner class Holder(binding: LayoutRecyclerItemBinding): RecyclerView.ViewHolder(binding.root) {
var text = binding.tvItem
}
이 Holder 클래스는 RecyclerView.ViewHolder 클래스를 상속받고 있으며, 생성자에 binding.root.
즉, binding되는 레이아웃의 가장 최상단 뷰를 전달해줍니다.
그리고 안에는 binding한 내용을 바탕으로 뷰들에 대한 변수를 선언해줬습니다.
// View Holder를 만들고 전해주는 부분
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val binding = LayoutRecyclerItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return Holder(binding)
}
이 Holder를 인스턴스화 해주고, 전해주는 부분이 위의 함수입니다.
먼저 binding 변수를 만들어서, Layout 하나를 inflate해줍니다.
그리고 이를 Holder 생성자에 넣어줘서 return해줍니다.
//홀더에 뷰들을 설정하는 부분
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.text.text = "하하$position"
holder.text.setOnClickListener {
itemClick?.onClick(it, position)
}
}
마지막으로, ViewHolder에 대한 정보를 기입해주는 함수인 onBindViewHolder입니다.
holder를 받고, position으로 몇 번째 아이템인지도 받게 됩니다.
여기서 text에 클릭 리스너를 설정했는데, 좀 특이한 방식을 사용합니다.
// 권장하는 방식 -> 인터페이스로 지정하고 이를 바깥에서 구현하는 걸 활용하는 방식을 자주 사용하고 권장된다
interface ItemClick {
fun onClick(view: View, position: Int)
}
var itemClick : ItemClick? = null
위 interface의 onClick 함수를 불러오는데, 이를 onCreate에서 itemClick을 구현합니다.
adapter.itemClick = object : MyAdapter.ItemClick {
override fun onClick(view: View, position: Int) {
Toast.makeText(this@MainActivity, "선택: $position", Toast.LENGTH_SHORT).show()
}
}
튜터님께서 이런 방식이 권장하는 방식이며, 나중에 이를 활용할 수도 있으니, 꼭 알아두고 가야 할 것 같습니다.
오늘은 챌린지반 특강도 있었는데요.
챌린지반에서는 디자인 패턴에 대해 배웠습니다.
디자인 패턴은 기본적으로 문제 해결을 위해 만들어진 패턴입니다.
제가 사용해본 것은 싱글톤 패턴이 있었는데, 공부하고 나니 조금 당황스러운 게 있었습니다.
생각보다 막 특별한 패턴이라기보다, 한번쯤 생각해볼 만한 내용들이 있었기 때문입니다.
하나씩 설명해보겠습니다.
먼저, Singleton 패턴은 하나의 객체가 하나의 인스턴스로 이루어진 경우입니다.
이 경우는 Kotlin에서 Object라는 좋은 문법을 기본적으로 제공해줘서 쉽게 구현할 수 있습니다.
그리고, Strategy 패턴입니다. 이 영어는 전략이라는 뜻인데, 기본이 되는 인터페이스는 같지만,
그를 구현하는 클래스들의 세부 알고리즘이 달라, 전략적으로 바뀔 수 있는 객체라는 뜻입니다.
다음은 Observer 패턴입니다. 객체 상태 변화를 관찰하는 관찰자들이 존재해, 변경 사항을 알려줍니다.
이는, 아직 따로 배우진 않았지만, LiveDate나 State같은 부분에서 쓰입니다.
또한 비슷한 경우로, onClickListener같은 Listener들도 존재합니다.
마지막으로, Decorator 패턴입니다. 데코레이터라는 말 그대로, 장식하듯이 이어붙일 수 있습니다.
예를 들어서, 커피가 있다면, 그 커피를 상속받는 아메리카노와, 이를 꾸며주기 위해 상속받는 데코레이터 클래스들이 있습니다.
이 데코레이터 클래스들의 생성자에 가장 기본 클래스를 넣어줘서, 마치 데코레이터 해주듯이, 계속해서 장식을 추가하는 방식입니다.
이외에도 다양한 패턴이 존재하는데, 이는 더 공부해봐야 할 것 같습니다.
MVVM 도 알려주셨지만, 아직 개념뿐이라, 이는 다음에 작성해 보겠습니다.
오늘부터는 하나에 먼저 집중하는 방식으로 진행하려 합니다.
알고리즘 공부하려 하고, 젯팩 컴포즈 공부하려 하고, 이런 방식은 저와 어울리지 않는 것 같습니다.
지금 재밌어보이는 안드로이드 MDC 먼저 끝내고 나머지를 진행해보도록 하겠습니다!
끝.