ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RecyclerView
    Android 2018. 12. 15. 21:21


    /*

    *  본 포스팅은 Udemy - Kotlin Android 부터 Firebase 서버 그리고 훌륭한 Chatbot 만들기를
       스스로 정리하고자 작성한 글입니다. 

    /* 


    Recycler View


    your app needs to display a scrolling list of elements based on large data sets (or data that frequently changes), you should use RecyclerView as described on this page.


    developer.android에 RecylerView를 찾으면 위와 같은 말을 찾을 수 있습니다. 

    scrolling 되고 큰 데이터에 기준되거나 변화 될때, 너는 RecylerView를 사용해야한다. 



    앱을 이용하다 보면 동일한 layout에 데이터만 바뀌어서 달라지는 화면을 볼 수 있습니다. 

    RecyclerView반복되는 item_list를 데이터만 바꾸어 보여주게 합니다. 



    [Goole Play_ 영화 Tab]




    * 그래서 어떻게 ? 


    맨 처음 Recycler View을 사용해 주기 위해서는 dependency 에서 해당 라이브러리를 설치해줘야합니다. 


       >   


    [ app의 오른쪽 버튼 > open Module setting> dependency > + ]


    누르고 appcompat 와 동일한 버전으로  설치합니다. 

    위와 같은 방법외에도 기본 xml 디자인 창에서 다운 받는 방법도 있습니다. 





    1.1 activity_main.xml 에 RecyclerView 만들기 

         activity_main에 반복적으로 나타 낼 화면을 RecyclerView로 설정합니다. 


    1.2 list_item.xml 만들기.  

    반복적으로 만들 list_item.xml 을 구성합니다. 


        

    <1.1 Recycler Layout>                         <1.2 List Item >





    여기서부터가 중요!

    2.1 MainActivity 

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

        //layoutManger 설정.
    var gridManager = GridLayoutManager(this,3)
    recyclerview.layoutManager= gridManager

    //recyclerview.layoutManager(GridLayoutManager(this,3) )



        //Adapter 설정.
    recyclerview.adapter=MainRecyclerViewAdapter()
    }

    * RecylcerView를 위해 필요한 것 


    1. layout manager
    : layout manager를 통해 View 를 그려줘야 합니다. 

    저는 GridLayoutManager로 화면 구성을 설정해주었습니다. 


    2. RecylcerView는 Adapter

    :  효율적으로 데이터와 뷰를 관리하기 위해 필요합니다.
      RecyclerView.ViewHolder를 상속받아 정의합니다.  

      View Holder 정의에 따라 UI가 표현됩니다. 또한 View Holder의 적용으로 View의 재사용이 가능합니다. 


    class MainRecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    var images = arrayOf(R.drawable.back1,R.drawable.back2,R.drawable.back3,R.drawable.back4)
    //2. 각각의 item 마다 데이터를 바인딩 .
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    var view = holder as CustomViewHolder
    view!!.imageView!!.setImageResource(images[position])

    }
    //1. 각각의 item 마다 디자인 레이아웃을 불러오기.
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    var view = LayoutInflater.from(parent!!.context).inflate(R.layout.item_recyclerlist,parent,false)
    var params = view.layoutParams

    if(viewType==0){
    params.height = (parent.measuredWidth/3)*2
    params.width=parent.measuredWidth
    view.layoutParams=params
    return CustomViewHolder(view)
    }
    else {
    params.height=parent.measuredWidth/3
    params.width=parent.measuredHeight/3
    view.layoutParams=params
    return CustomViewHolder(view)
    }
    }
    // postion에 따라서 type을 바꿔주는 기능
    override fun getItemViewType(position: Int): Int {
    if(position==0)
    return 0
    else
    return 1
    //return 된 결과는 oncreateViewHolder viewType으로 넘어 간다.
    }

    // 슈퍼 클래스에 아무것도 생성이 안되었다고 에러가 발생한다. 슈퍼클래스는 상속해주는 부모 뷰를 말한다.
    class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    var imageView : ImageView? = null
    init{
    imageView=view!!.findViewById(R.id.imageview_list)
    }

    }
    //3. item 의 개수를 카운트.
    override fun getItemCount(): Int {
    return 4
    }
    }

     * 기본적으로 RecyclerViewAdapter를 만들면 3가지 함수를 implement 합니다. 


    1. onCreateViewHolder ( parent: ViewGroup,viewType: Int) : RecyclerView.VeiwHoldeer () {}

    각각의 item 마다 디자인한 레이아웃을 불러옵니다.


    2. onBindViewHolder(hoder: RecyclerView.ViewHodler,position:Int) {}

    각각의 item 마다 데이터를 바인딩 해줍니다.


    3. getItemCount() : Int{}     item의 개수를 카운트 해줍니다.


    TMI)


     저 같은 경우는 인스타그램같이 한 이미지뷰를 그리드하게 나타내는 것이였기에 

     list item 에 들어갈 이미지들을 배열로 정의하고 

    var images = arrayOf(R.drawable.back1,R.drawable.back2,R.drawable.back3,R.drawable.back4)


    디자인한 레이아웃을 imageview로 해당 images의 position으로 접근했습니다.  

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    var view = holder as CustomViewHolder
    view!!.imageView!!.setImageResource(images[position])
    }

    위 코드에서 as란 코틀린 문법 중 스마트 캐스팅에 해당하는 말로

    명시적인 타입 캐스팅을 사용합니다. 

    즉 holder : RecyclerView.ViewHolder를 CustomViewHolder로 타입 캐스팅하는 것을 의미합니다. 


      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    var view = LayoutInflater.from(parent!!.context).inflate(R.layout.item_recyclerlist,parent,false)
    var params = view.layoutParams

    if(viewType==0){
    params.height = (parent.measuredWidth/3)*2
    params.width=parent.measuredWidth
    view.layoutParams=params
    return CustomViewHolder(view)
    }
    else {
    params.height=parent.measuredWidth/3
    params.width=parent.measuredHeight/3
    view.layoutParams=params
    return CustomViewHolder(view)
    }
    }

    위 함수에서 

    LayoutInflater, params 라는 개념에 대한 정확한 이해가 필요하였는데, 

    LayoutInflater란 XML에 정의된 Resource(자원) 들을 View의 형태로 반환해 줍니다. 

    부모 뷰그룹에서 item_reyclerlist.xml을 view 형태로 반환하는 것을 의미하는 것입니다. 


    cotext에 NullException관한 추가적 공부가 필요할 듯한데... 일단은 추후에 포스팅을 작성하겠습니다. 


    if else 구문 에서는 

    첫번째 온 Image에 대해서는 부모 Width의 높이만큼 높이는 (부모 너비 /3 *2 )만큼,  

    나머지 image에 대해서는 부모 layout의 높이, 넓이의 1/3 처럼 정의됩니다. 


    결과적으로 완성된 화면은 아래와 같습니다. 







    LIST

    댓글

Designed by Tistory.