[Android] IntelliJ #9 RecyclerView

현지·2022년 2월 9일
0

RecyclerView

  • 원하는대로 리스트를 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)
    }
}

0개의 댓글