본문 바로가기

Android

Recycler View

Recyler View 정의

1. RecyclerView 

 

1) ListView

- 아래로 스크롤 할 때, 맨 위의 객체 삭제하고 아랫 부분에 객체를 새로 생성하여 사용

- 스크롤을 반복하면 수백, 수천개의 View 객체가 생성/삭제

2) RecylcerView

- 아래로 스크롤 할 때, 맨 위의 객체를 맨 아래로 이동시켜 재활용 (객체에 담겨지는 데이터는 새로 갱신)

- 맨 처음 화면에 보여지는 View가 10개면 실제 데이터가 수백, 수천개라도 오로지 10개의 View 객체만 생성해 재활용

 

2. ViewHolder

- ViewHolder : 맨 처음 10개의 View객체를 기억하고 있을(홀딩) 객체 (맨 처음 화면에 보여지는 View가 10개라면)

- ViewHolder로 기억한 View 객체는 맨 위의 객체를 맨 아래로 이동시켜 재활용

 

// ViewHolder 코드
class ViewHolder(private val binding: ItemRvBinding) : RecyclerView.ViewHolder(binding.root){
	var textView: TextView = binding.tvItem
}

 

  • 변수에 다른 데이터를 저장하며 모든 데이터 목록 나열

 

사용법

1. Recycler VIew 생성

 

2. RecyclerView를 구성할 아이템 형식 지정

- layout -> New -> Layout Resource File

- TextView만 지정

 

3. RecyclerViewAdapter 생성

1) New -> Kotlin Class

 

2) RVAdapter 코드

- RecyclerView.Adapter 상속 받기

- 문자열 리스트를 데이터로 가져오기

- View Holder 패턴 : 많은 수의 아이템을 화면에 표시할 때 효율적으로 메모리를 관리하고 스크롤 성능을 최적화

 

//RVAdapter 생성자 : 문자열 데이터
class RVAdapter(private val items:ArrayList<String>) : RecyclerView.Adapter<RVAdapter.ViewHolder>() {


    // 생성자에서 ItemRvBinding을 받아와 itemRecyclerView.xml의 요소에 접근할 수 있게 설정
    class CustomViewHolder(private val binding: ItemRvBinding) : RecyclerView.ViewHolder(binding.root){
        var textView: TextView = binding.tvItem
    }


    // data의 개수 반환 (문자열 데이터의 크기)
    override fun getItemCount(): Int {
        return items.size
    }


    // View 객체를 담고 있는 ViewHolder 생성 : XML 레이아웃을 인플레이트하고 새로운 뷰 홀더 객체 생성
    // 리스트 목록이 10개라면 13~15정도 여유있게 호출
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        
        // LayoutInflater : XML 레이아웃 파일을 실제 뷰 객체로 변환
        // context : 액티비티에서 담고 있는 모든 정보
        // parent.context : 어댑터랑 연결된 activity context
        val view = ItemRvBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return CustomViewHolder(view)
    }


    // ViewHolder에 data를 바인딩
    // 데이터가 스크롤 되어서 맨 위에 있던 객체가 맨 아래로 이동하면 레이아웃은 재사용, 데이터는 새롭게 바인딩
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textView.text = items[position]
    }

}

 

 

4. Adapter 연결

1) FragmentTodo

- 아이템에 넣을 데이터 생성

- RecyclerView에 adapter 연결

- layoutManager로 나열 방식 지정

 

class FragmentTodo : Fragment() {

    private lateinit var binding: FragmentTodoBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        binding = FragmentTodoBinding.inflate(inflater, container, false)
        return binding.root
    }

    // 프래그먼트 뷰가 생성되고 나서 호출 : RecyclerView에 표시할 준비
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val items = addData()
        val adapter = RVAdapter(items)

        //recycelrView 어댑터 연결
        binding.recyclerView.adapter = adapter

        //LinearLayoutManager : 세로로 리스트 나열
        binding.recyclerView.layoutManager  = LinearLayoutManager(requireContext())
    }

    // RecyclerView에 들어갈 list 생성
    fun addData():ArrayList<String>{
        val list = ArrayList<String>()
        for ( i in 0 until 20){
            list.add("todo")
        }
        return list
    }

}

 

2) FragmentBookmark

// 프래그먼트 초기화 파라미터
private const val ARG_PARAM1 = "param1"

class FragmentBookmark : Fragment() {

    //변수 설정
    private var param1: String? = null

    //뷰 바인딩 객체 저장
    private var _binding: FragmentBookmarkBinding?= null
    private val bbinding get() = _binding!!

    // 프래그먼트 생성될 때 호출
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //arguments : Bundle 객체, 프래그먼트 간 데이터 전달
        arguments?.let {
            //초기화 파라미터 가져와서 변수에 저장
            param1 = it.getString(ARG_PARAM1)
        }
    }

    // 프래그먼트 뷰 생성하고 초기화
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentBookmarkBinding.inflate(inflater, container, false)
        return bbinding.root
    }

    // 프래그먼트 소멸될 때 호출
    override fun onDestroy() {
        _binding = null
        super.onDestroy()
    }

    // 뷰가 생성되고 난 뒤 호출
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val items = addData()
        val adapter = RVAdapter(items)
        bbinding.recyclerView2.adapter = adapter
        bbinding.recyclerView2.layoutManager = LinearLayoutManager(requireContext())
    }


    fun addData():ArrayList<String>{
        val list = ArrayList<String>()
        for ( i in 0 until 20){
            list.add("bookmark")
        }
        return list
    }

    companion object {
        // 팩토리 메서드 : 파라미터를 사용해 새로운 프래그먼트 인스턴스 생성하는 데 사용
        @JvmStatic
        fun newInstance(param1: String) =
            FragmentBookmark().apply {
                arguments = Bundle().apply {
                    //ARG_PARAM1이라는 키에 param1 값 할당
                    putString(ARG_PARAM1, param1)
                }
            }
    }
}

 

 

 

 

 

 

 

 

 

'Android' 카테고리의 다른 글

RecyclerView에 데이터 추가하기 (Fragment, ViewPager2)  (1) 2023.08.23
View와 ViewGroup  (2) 2023.08.10
TabLayout과 ViewPager2 연결하기  (0) 2023.08.09
Status Bar (상태바)  (0) 2023.08.08
Button Icon  (0) 2023.08.08