[Android / Kotlin] Parcelize 사용하여 intent에 data class 전달하기

Subeen·2024년 1월 6일
0

Android

목록 보기
32/71

오늘은 메인 액티비티에서 서브 액티비티로 data class 객체를 Intent의 데이터로 전달 하기 위해 Parcelize를 사용하였는데 이 내용을 정리해보려 한다.

build.gradle (:app)

  • app 수준의 build.gradle 파일의 plugins에 id("kotlin-parcelize")를 추가한다.
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("kotlin-parcelize") // add
}

Data class

  • @Parcelize 어노테이션을 달아준다.
  • Null 값을 허용한다.
  • : Parcelable을 작성한다.
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
data class SignUpUserEntity(
    var name: String?,
    var email: String?,
    var emailProvider: String?,
    var password: String?
) : Parcelable

MainActivity

  • MainActivity 에서 인텐트를 사용해 SignUpUserEntity 클래스의 객체를 DetailActivity에 넘기는 작업을 한다.
    • 화면 전환 역할을 하는 인텐트 생성
    • 입력받은 값으로 ProductEntity 객체 생성
    • 인텐트에 생성한 객체 삽입
adapter.itemClick = object : ProductAdapter.ItemClick {
	override fun onItemClick(view: View, position: Int) {
		val intent = Intent(this@MainActivity, DetailActivity::class.java)
		val data = ProductEntity(
			items[position].id,
			items[position].resId,
			items[position].name,
			items[position].explain,
			items[position].seller,
			items[position].price,
			items[position].location,
			items[position].like,
			items[position].chat
		)
		intent.putExtra("data", data)
		startActivity(intent)
	}
}
class MainActivity : AppCompatActivity() {
    companion object {
        const val EXTRA_PRODUCT_ENTITY = "extra_product_entity"
    }

    private val binding: ActivityMainBinding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        this.onBackPressedDispatcher.addCallback(this, onBackPressedCallback)

        initView()
    }

    private val onBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            showAlertDialog()
        }
    }

    private fun showAlertDialog() {
        val builder = AlertDialog.Builder(this@MainActivity)
        builder.apply {
            setTitle(getString(R.string.dialog_title))
            setMessage(getString(R.string.dialog_message))
            setIcon(R.drawable.img_main_chat_16dp)
        }

        val listener = DialogInterface.OnClickListener { _, which ->
            when (which) {
                DialogInterface.BUTTON_POSITIVE -> finish()
                DialogInterface.BUTTON_NEGATIVE -> Unit
                else -> Unit
            }
        }
        builder.setPositiveButton(getString(R.string.dialog_button_positive), listener)
        builder.setNegativeButton(getString(R.string.dialog_button_negative), listener)
        builder.show()
    }

    private fun setSpinnerLocation() {
        binding.spinnerLocation.adapter = ArrayAdapter(
            this@MainActivity,
            android.R.layout.simple_spinner_dropdown_item,
            listOf(
                getString(R.string.location_0)
            )
        )
    }

    private fun initView() {
        setSpinnerLocation()

        val items = loadList()
        val adapter = ProductAdapter(items)
        binding.productRecyclerView.adapter = adapter
        binding.productRecyclerView.layoutManager = LinearLayoutManager(this)
        binding.productRecyclerView.addItemDecoration(
            DividerItemDecoration(this, LinearLayoutManager.VERTICAL)
        )

        adapter.itemClick = object : ProductAdapter.ItemClick {
            override fun onItemClick(view: View, position: Int) {
                val intent = Intent(this@MainActivity, DetailActivity::class.java)
                val data = ProductEntity(
                    items[position].id,
                    items[position].resId,
                    items[position].name,
                    items[position].explain,
                    items[position].seller,
                    items[position].price,
                    items[position].location,
                    items[position].like,
                    items[position].chat
                )
                intent.putExtra(EXTRA_PRODUCT_ENTITY, data)
                startActivity(intent)
            }
        }

        binding.ivNotification.setOnClickListener {
            notification()
        }
    }

    private fun notification() {
        val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager

        val builder: NotificationCompat.Builder
        // 33 버전 이상
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (!NotificationManagerCompat.from(this).areNotificationsEnabled()) {
                // 알림 권한이 없다면, 사용자에게 권한 요청
                val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
                    putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                }
                startActivity(intent)
            }
        }
        // 26 버전 이상
        val channelId = "one-channel"
        val channelName = "My Channel One"
        val channel = NotificationChannel(
            channelId,
            channelName,
            NotificationManager.IMPORTANCE_DEFAULT
        ).apply {
            // 채널에 다양한 정보 설정
            description = "My Channel One Description"
            setShowBadge(true)
            val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
            val audioAttributes = AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_ALARM)
                .build()
            setSound(uri, audioAttributes)
            enableVibration(true)
        }
        // 채널을 NotificationManager에 등록
        manager.createNotificationChannel(channel)

        // 채널을 이용하여 builder 생성
        builder = NotificationCompat.Builder(this, channelId)

        // 알림의 기본 정보
        builder.run {
            setSmallIcon(R.mipmap.ic_launcher)
            setWhen(System.currentTimeMillis())
            setContentTitle(getString(R.string.notification_title))
            setContentText(getString(R.string.notification_message))
        }

        manager.notify(11, builder.build())
    }
}

DetailActivity

  • EXTRA_PRODUCT_ENTITY으로 넘어온 ProductEntity의 객체를 productEntity에 저장한다.
private val productEntity: ProductEntity? by lazy {
	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
		intent?.getParcelableExtra(
		)
	} else {
		intent?.getParcelableExtra(
			EXTRA_PRODUCT_ENTITY
		)
	}
}
class DetailActivity : AppCompatActivity() {
    private val binding: ActivityDetailBinding by lazy {
        ActivityDetailBinding.inflate(layoutInflater)
    }

    private val productEntity: ProductEntity? by lazy {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            intent?.getParcelableExtra(
                EXTRA_PRODUCT_ENTITY, ProductEntity::class.java
            )
        } else {
            intent?.getParcelableExtra(
                EXTRA_PRODUCT_ENTITY
            )
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        // TODO 화면에 데이터 출력
        Log.d(
            "DetailActivity", "${productEntity?.id}," +
                    "${productEntity?.resId}," +
                    "${productEntity?.name}," +
                    "${productEntity?.explain}," +
                    "${productEntity?.seller}," +
                    "${productEntity?.price}," +
                    "${productEntity?.location}," +
                    "${productEntity?.like}," +
                    "${productEntity?.chat}"
        )
    }
}

참조
인텐트로 객체 전달하기

profile
개발 공부 기록 🌱

0개의 댓글