RecyclerView로 동적목록을 만들 수 있는데 앱을 만들 때 정말 많이 쓰이는 요소이다.
처음에 구현을 배울 땐 Activity로 구현하는 것으로 익혔으나 어플 내에서는 생각보다 Fragment가 훨씬 많이 쓰이는 것을 깨달았다. 그래서 Fragment안에 RecyclerView를 띄울 수 있도록 할것이다.
*주요클래스
이 동적 목록을 만드는데 필요한 클래스들이다.
-RecyclerView: 데이터에 해당하는 뷰가 포함된 ViewGroup이다. 뷰 자체이므로 레이아웃에 RecyclerView를 추가하면 된다.
-ViewHolder: 목록의 각 개별적 요소들은 뷰 홀더 객체로 정의된다. 뷰 홀더가 생성되었을 때는 뷰 홀더에 연결된 데이터가 없다. 뷰 홀더가 생성된 후 RecyclerView가 뷰 홀더를 뷰의 데이터에 바인딩한다.
-Adapter: RecyclerView는 뷰를 요청한 다음 어댑터에서 메서드를 호출하여 뷰를 뷰의 데이터에 바인딩한다.
<구현방법>
1.
우선 activity_main.xml에 FrameLayout을 넣어준다. 그리고 아이디를 부여한다. 이 부분에 fragment화면을 올릴것이다.
2.동적 목록을 넣어줄 fragment.xml과 fragment.kt파일을 동시 생성해준다.
<androidx.recyclerview.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/rv_profile2"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="horizontal"
tools:listitem="@layout/item_recycler_ex2"
/>
다음과 같이 id,방향,그리고 Recyclerview 목록의 요소부분의 디자인을 해줄 xml파일을 listitem부분에 정의해준다.
item_recycler_ex2.xml파일도 생성해주고 만들고 싶은 목록 아이템을 선언해준다.
3.데이터 클래스 만들기
data class ProfileData2(
val img:Int,
val title:String,
val little:String
)
리스트의 각 아이템의 내용이 담길 데이터 클래스를 만든다.
4.어댑터 및 뷰홀더 구현
가장 중요한 부분이라고 생각한다.
adapter을 정의시 필수 구현해야하는 3가지 메서드들이 있다.
onCreateViewHolder(): ViewHolder와 그에 연결된 View를 생성하고 초기화하지만 뷰의 콘텐츠를 채우지는 않는다. 각 행의 레이아웃(item_recycler_ex2)를 inflate하여 뷰홀더 생성해준다.
onBindViewHolder():RecyclerView가 ViewHolder를 테이터와 연결할 때 호출한다. 데이터를 사용해 뷰 홀더의 레이아웃을 채운다.
getItemCount(): RecyclerView는 데이터 세트 크기를 가져올 때 이 메서드를 호출한다. RecyclerView는 이 메서드를 사용해서 항목을 추가로 표시할 수 없는 상황을 확인한다.
class ProfileAdapter2(private val profiledatalist: ArrayList<ProfileData2>):
RecyclerView.Adapter<ProfileAdapter2.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_recycler_ex2,
parent,false)
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = profiledatalist[position]
//img title little
holder.titleimg.setImageResource(currentItem.img)
holder.title.text = currentItem.title
holder.little.text = currentItem.little
}
override fun getItemCount(): Int {
return profiledatalist.size
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val titleimg:ImageView = itemView.findViewById(R.id.popularphoto)
val title:TextView = itemView.findViewById(R.id.title)
val little:TextView = itemView.findViewById(R.id.little)
}
}
다음과 같이 된다. 그리고 참고로 이미지들은 drawable파일에 모두 넣어주었고 동적 목록에 들어가는 모든 Textview들은 strings.xml파일에 미리 정의해놓았다.
5. 리사이클러뷰에 어댑터 붙이기
Fragment.kt파일에서 fragment위에 띄울 수 있도록 생명주기랑 관련하여 정의해주어야 한다.
private lateinit var adapter2: ProfileAdapter2
private lateinit var recyclerView:RecyclerView
private lateinit var profile2ArrayList:ArrayList<ProfileData2>
lateinit var ImageId:Array<Int>
lateinit var title:Array<String>
lateinit var little:Array<String>
다음과 같이 이 파일에서 쓸 변수들을 연결시켜준다.
private fun dataInitialize(){
profile2ArrayList= ArrayList<ProfileData2>()
ImageId=arrayOf(
R.drawable.food,
R.drawable.food2,
R.drawable.weather,
R.drawable.my
)
title = arrayOf(
getString(R.string.title1),
getString(R.string.title2),
getString(R.string.title4),
getString(R.string.title3)
)
little = arrayOf(
getString(R.string.title1),
getString(R.string.title2),
getString(R.string.title4),
getString(R.string.title3)
)
for(i in ImageId.indices){
val little = ProfileData2(ImageId[i], title[i],little[i])
profile2ArrayList.add(little)
}
}
그리고 ArrayList를 만들고 화면에 보여질 데이터들을 집어넣는다.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dataInitialize()
//val layoutManager = LinearLayoutManager(context)
val layoutManager = LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL, false)
recyclerView = view.findViewById(R.id.rv_profile2)
recyclerView.layoutManager = layoutManager
//recyclerView.setHasFixedSize(true)
adapter2 = ProfileAdapter2(profile2ArrayList)
recyclerView.adapter = adapter2
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
//return inflater.inflate(R.layout.fragment_home, container, false)
return inflater.inflate(R.layout.fragment_home, container,false)
}
onCreateView()로 반환되는 view객체는 onViewCreated()의 파라미터로 전달된다.
리사이클러뷰에 어댑터도 붙여주고 레이아웃 매니저도 설정해주면된다. 이때 그림의 저 상황은 가로 스크롤을 가능하게 하기 위해서 바꾸었다.
이 후 MainActivity.kt에서 프래그먼트를 띄우는 작업만 해준다면 RecyclerView를 프래그먼트에서 구현할 수 있다.
(구현하면서 궁금했던 context에 대하여)
-어플의 현재 상태를 갖고 있음
-시스템이 관리하고 있는 액티비티, 어플의 정보를 얻기 위해 사용
-안드로이드 시스템 서비스에서 제공하는 API에 접근하기 위해 사용
-Activity, Application 클래스는 context클래스를 상속받은 클래스
두가지로 나뉜다=Application Context/ Activity Context
-Application Context
Activity에서 applicationContext라는 프로퍼티를 통해 얻을 수 있는 싱글톤 인스턴스이다.
라이프사이클과 묶여있어 현재 context가 종료되고 나서도 context가 필요한 작업이나 액티비티 범위를 벗어난 곳에서 context가 필요한 작업에 적합
-Activity Context
해당 Context 는 액티비티 안에서만 사용 가능하다. 특정 Activity 의 라이프 사이클에 종속되어 있다. 이 녀석은 Activity 스코프 내에서 사용될 때 넘겨주거나, Activity 와 라이프사이클이 같은 객체를 생성할 때 넘겨준다. 즉, Activity 가 소멸되면 해당 Context 도 같이 소멸되는 것이다.
'Frontend > Kotlin' 카테고리의 다른 글
Solution:카카오 소셜 로그인 구현 (0) | 2023.01.10 |
---|---|
Unit 5 (0) | 2023.01.10 |
Unit 3 solution (0) | 2022.11.20 |
unit 3 강의 정리 (0) | 2022.11.16 |
2번째 스터디 과제 (0) | 2022.11.14 |