- 원하는대로 리스트를 custom할 수 있다.
- 하나를 눌렀을 때, 해당 정보를 가지고 detail페이지로 이동한다.
✅ app > build.gradle에 추가
-> Sync now 꼭 누르기!!
implementation 'androidx.recyclerview:recyclerview:1.1.0' // 추가 implementation 'com.github.bumptech.glide:glide:4.11.0' // 추가 annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' // 추가
✅ activity_main.xml
- RecyclerView추가
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="680dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
✅ res > layout > view_item_layout.xml 추가
- RecyclerView에 추가할 layout 만들기
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="60dp" android:layout_margin="5dp"> <ImageView android:id="@+id/img_profile" android:layout_width="54dp" android:layout_height="54dp" android:layout_marginStart="8dp" android:layout_marginTop="4dp" android:layout_marginLeft="8dp" android:layout_marginBottom="4dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/userNameTxt" android:text="이름" android:layout_width="177dp" android:layout_height="28dp" android:textSize="20sp" android:textStyle="bold" app:layout_constraintStart_toEndOf="@+id/img_profile" android:layout_marginStart="8dp" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="4dp"/> <TextView android:id="@+id/payTxt" android:text="연봉" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toEndOf="@+id/img_profile" android:layout_marginStart="8dp" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="4dp"/> <TextView android:id="@+id/addressTxt" android:text="주소" android:layout_width="272dp" android:layout_height="wrap_content" app:layout_constraintStart_toEndOf="@+id/payTxt" android:layout_marginStart="16dp" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="4dp"/> </androidx.constraintlayout.widget.ConstraintLayout>
✅ DataVo.kt 추가
package com.example.sample30 import android.os.Parcel import android.os.Parcelable class DataVo(val name:String?, val id:String?, val address:String?, val pay:Int, val photo:String?) : Parcelable{ constructor(parcel:Parcel) : this( parcel.readString(), parcel.readString(), parcel.readString(), parcel.readInt(), parcel.readString() ){} override fun writeToParcel(parcel: Parcel, p1: Int) { parcel.writeString(name) parcel.writeString(id) parcel.writeString(address) parcel.writeInt(pay) parcel.writeString(photo) } override fun describeContents(): Int { return 0 } companion object CREATOR : Parcelable.Creator<DataVo>{ override fun createFromParcel(parcel: Parcel): DataVo { return DataVo(parcel) } override fun newArray(size: Int): Array<DataVo?> { return arrayOfNulls(size) } } }
✅ CustomAdapter.kt추가
package com.example.sample30 import android.content.Context import android.content.Intent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide class CustomAdapter(private val context:Context, private val dataList: ArrayList<DataVo>) : RecyclerView.Adapter<ItemViewHolder>(){ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { val view = LayoutInflater.from(context).inflate(R.layout.view_item_layout, parent, false) return ItemViewHolder(view) } override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { holder.bind(dataList[position], context) } override fun getItemCount(): Int { return dataList.size } } class ItemViewHolder(itemView:View) : RecyclerView.ViewHolder(itemView){ private val userPhoto = itemView.findViewById<ImageView>(R.id.img_profile) private val userName = itemView.findViewById<TextView>(R.id.userNameTxt) private val userPay = itemView.findViewById<TextView>(R.id.payTxt) private val userAddress = itemView.findViewById<TextView>(R.id.addressTxt) //data -> resource (=binding) fun bind(dataVo: DataVo, context: Context){ //사진 세팅 if(dataVo.photo != ""){ val resourceId = context.resources.getIdentifier(dataVo.photo, "drawable", context.packageName) if(resourceId > 0){ //이미지를 얻어옴 userPhoto.setImageResource(resourceId) }else{ //이미지를 얻어오지 못함 //로딩을 다시 해줌 Glide.with(itemView).load(dataVo.photo).into(userPhoto) //userPhoto.setImageResource(R.mipmap.ic_launcher_round) //=> 아무 이미지 출력 } }else{ userPhoto.setImageResource(R.mipmap.ic_launcher_round) //이미지 없다. 지원되는 아무 이미지 뿌려라 } //TextView에 데이터를 세팅 userName.text = dataVo.name userPay.text = dataVo.pay.toString() userAddress.text = dataVo.address //itemview를 클릭시 이벤트 발생 itemView.setOnClickListener{ println(dataVo.name + " " + dataVo.photo) //ProfileDetailActivity로 이동 Intent(context, ProfileDetailActivity::class.java).apply { //짐싸! putExtra("data", dataVo) //현재 화면 위에 덮어쓰는 느낌 addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }.run { context.startActivity(this) } } } }
✅ MainActivity
- userList에 추가하는 경우 drawable에 추가한 이미지명과 동일해야 함
package com.example.sample30 import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView class MainActivity : AppCompatActivity() { var userList = arrayListOf<DataVo>( DataVo("김철수", "kcs", "서울시", 3000000, "kim"), DataVo("박상현", "psh", "부산시", 5000000, "park"), DataVo("최진형", "cjh", "광주시", 4000000, "choi"), DataVo("정수동", "jsd", "충주시", 4500000, "jung") //없는 이미지 일때 확인 ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var recyclerView = findViewById<RecyclerView>(R.id.recyclerView) val mAdapter = CustomAdapter(this, userList) recyclerView.adapter = mAdapter val layout = LinearLayoutManager(this) recyclerView.layoutManager = layout recyclerView.setHasFixedSize(true) } }
✅ activity_profile_detail.xml추가
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ProfileDetailActivity"> <ImageView android:layout_width="108dp" android:layout_height="108dp" tools:srcCompat="@tools:sample/avatars" android:id="@+id/img_profile" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.248"/> <TextView android:id="@+id/userName" android:text="이름" android:textSize="20dp" android:gravity="center" android:layout_width="278dp" android:layout_height="53dp" app:layout_constraintTop_toBottomOf="@+id/img_profile" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="52dp"/> <TextView android:id="@+id/userId" android:text="아이디" android:textSize="20dp" android:gravity="center" android:layout_width="278dp" android:layout_height="53dp" app:layout_constraintTop_toBottomOf="@+id/userName" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" android:layout_marginTop="52dp"/> <TextView android:id="@+id/userPay" android:text="연봉" android:textSize="20dp" android:gravity="center" android:layout_width="278dp" android:layout_height="53dp" app:layout_constraintTop_toBottomOf="@+id/userId" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.157"/> </androidx.constraintlayout.widget.ConstraintLayout>
✅ ProfileDetailActivity
package com.example.sample30 import android.os.Bundle import android.widget.ImageView import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import com.bumptech.glide.Glide class ProfileDetailActivity : AppCompatActivity() { /*activity 추가하면 AndroidManifest.xml에 추가해줘야 함*/ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_profile_detail) //짐 풀러 => CustomAdapter에서 보내준 데이터 값 val data = intent.getParcelableExtra<DataVo>("data") println(data?.name + " " + data?.id) val imageView = findViewById<ImageView>(R.id.img_profile) val userId = findViewById<TextView>(R.id.userId) val userName = findViewById<TextView>(R.id.userName) val userPay = findViewById<TextView>(R.id.userPay) //imageView.setImageResource(R.drawable.kim) //사용할 수 없음 => R.drawable.kim는 숫자로 이루어져 있음 => 아래 함수 사용 //imageView에 data?.photo명의 이미지를 drawing해라 Glide.with(this).load(getImage(data?.photo)).into(imageView) userId.text = data?.id userName.text = data?.name userPay.text = data?.pay.toString() } fun getImage(imageName:String?) : Int{ //drawable폴더에 있는 imageName이 int형태로 return 됨 return resources.getIdentifier(imageName, "drawable", packageName) } }