처음 배울 때는 Scroll View와 LinearLayout을 이용하여 Data List를 보여주었다.

나쁘지 않다 생각했으나 아무것도 모를 때이기에 그렇게 생각했다ㅋㅋ

 

여기서 한 단계 더 배워 Adapter View를 배워서 ListView와 GridView를 통해 아이템들을 보여주었다.

그래 이거지,, 동적으로 추가도 가능해지며 좀 더 그럴 듯 해보였다.

그 전에 스크롤 뷰에서 아이템의 위치 값을 이용하기 위해 intent로 쌩쇼를 한게 부끄러울 정도다.

하지만 이런 ListView와 GridView도 문제점을 가지고 있었다.

Data가 100개, 1000개, 10000개라면?? 혹은 Data가 동적으로 계속 변경된다면?

 

앱은 과부하되어 실행되지 않을 수 있겠다...

 

왜냐하면 기존의 ListView나 GridView는 밑으로 스크롤 할 때마다 위에 있던 아이템은 삭제되고, 맨 아래의 아이템은 생성 되길 반복하기 때문이다. 한 마디로 비효율적으로 일을 하는 형태이다.

 

이런 단점을 보완하기 위해 나온 이름하야 리사이클러 뷰!!

RecyclerView란?

리사이클러 뷰는 현재 현업에서 리스트 형태의 Data를 표시하는데 무조건 쓰이는 가장 최신의 위젯이다.

아래 그림과 같이 리스트를 스크롤 할 때, 위에 있던 아이템은 재활용 돼서 아래로 이동하여 재사용 한다.

많은 아이템을 효율적으로 관리하고 보여주는 역할을 한다.

 

Recycler View를 사용할 땐 3가지가 필요하다.

 

1. LayoutManager

  • LayoutManager는 RecyclerView 내부의 아이템들이 어떻게 배치될지를 결정한다.
  • 기본 제공되는 **LayoutManager**로는 LinearLayoutManager, GridLayoutManager, StaggeredGridLayoutManager 등이 있다.

recyclerView.layoutManager = LinearLayoutManager(this) // 수직 리스트를 위한 LinearLayoutManager
// 또는
recyclerView.layoutManager = GridLayoutManager(this, 2) // 2열 그리드를 위한 GridLayoutManager

 

2. RecyclerView.Adapter

  • RecyclerView에 표시될 데이터와 해당 데이터를 보여줄 ViewHolder를 연결한다.
  • Adapter는 데이터셋의 변경 사항을 RecyclerView에 알리고, 데이터를 기반으로 뷰를 생성합니다.
class MyAdapter(private val dataList: MutableList<String>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView = view.findViewById(R.id.textView)
        val thumbnailView: ImageView = view.findViewById(R.id.thumbnail)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false)
        return MyViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        Log.d("RecycleView", "onBindViewHolder :$position")
        holder.textView.text = dataList[position]
        holder.thumbnailView.setImageUri(dataList[position].thubnailUrl)
    }

    override fun getItemCount() = dataList.size

    // 데이터 추가
    fun addItem(data: String) {
        dataList.add(data)
        notifyItemInserted(dataList.size - 1)
    }

    // 데이터 삭제
    fun removeItem(position: Int) {
        if (position < dataList.size) {
            dataList.removeAt(position)
            notifyItemRemoved(position)
        }
    }
}

3. ViewHolder

  • RecyclerView의 개별 아이템 뷰를 위한 객체이다.
  • 아이템 뷰의 모든 서브 뷰를 담고 있어 재사용과 성능 최적화에 도움을 준다.
inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val thumbnailView: ImageView = view.findViewById(R.id.thumbnailView)
        val titleView: TextView = view.findViewById(R.id.titleView)
        // 여기에 필요한 다른 뷰를 추가할 수 있다.
    }

Scope Function

자기 자신의 객체를 전달해서 효율적인 처리를 한다.

  Scope에서 접근방식 this Scope에서 접근방식 it
블록 수행 결과를 반환 run, with let
객체 자신을 반환 apply also

 

let function  

// let
var strNum = "10"

    var result = strNum?.let {
        // 중괄호 안에서는 it으로 활용함
        Integer.parseInt(it)
    }

 

 

run function & with function

+ run은 with와 달리 null 체크 가능

+ with는 반드시 null이 아닐 때만 사용 + this생략해서 사용 가능

    // run
    var student = Student("참새", 10)
    student?.run {
        displayInfo()
    }
    
    // with
    var alphabets = "abcd"
    with(alphabets) {
//    	var result = this.subSequence(0,2)
      	var result = subSequence(0,2)
      	println(result)
    }

 

also function & apply function

// also
    var student = Student("참새", 10)
    var result = student?.also {
        it.age = 50
    }
    result?.displayInfo()
    student.displayInfo()
    
// apply
    var student = Student("참새", 10)
    var result = student?.apply {
        student.age = 50
    }
    result?.displayInfo()
    student.displayInfo()

 

 

처음 이 문제를 생각했을 땐 굉장히 복잡하게 느껴졌다.

 

mapIndexed로 접근해서 인덱스 값으로 접근을 해볼까 이런식으로,,

정렬을 보면 sort를 떠올려야하는데 아직 많이 부족하다..

 

한참을 헤매다가 결국 검색을 했다.. 

 

검색결과 다중 정렬이라는 아주 멋지고 간단한 방법을 발견했다.

 

하나 이상의 기준을 가지고 정렬을 해야할 때 사용하면 정말 쉽게 구현가능하다.

 

바로 sortedWith() 함수와 compareBy를 comparator로 사용하는 것이다.

 

코드를 먼저 보자.

 

class Solution {
    fun solution(strings: Array<String>, n: Int): Array<String> {
        var answer = arrayOf<String>()
        
        answer = strings.sortedWith(compareBy({it[n]}, {it})).toTypedArray()
        
        return answer
    }
}

 

우선 sortedWith 함수는 원본 리스트를 바꾸지 않고 인자로 comparator를 받아 여러개의 정렬 기준으로 새로운 리스트를 반환한다.

 

여기서는 compareBy라는 comparator를 사용하여 두 개의 정렬 기준에서 우선 순위를 부여하여 첫번째로 it[n]을 기준으로 정렬하고 그 후에 그 기준을 적용시킨 채로 두 번째 정렬 기준인 기본 오름차순 정렬을 해준것이다.

(tip: sortedBy는 정렬 기준이 하나 일 때 사용^^)

 

compareBy는 기본적으로 오름차순 정렬이며 내림차순으로 하고 싶을 때는 compareByDescending()을 써주면 된다.

 

+ Recent posts