카테고리 없음
9주차 3일 이모저모
시계속세상은아직돌아가는중
2023. 9. 6. 21:24
1. cointoss minigame
package com.example.nbcamp_teamproject_call.minigame
import android.content.Context
import android.content.Intent
import android.media.MediaPlayer
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.ImageView
import android.widget.Toast
import com.example.nbcamp_teamproject_call.R
import com.example.nbcamp_teamproject_call.databinding.CoinTossActivityBinding
import java.util.Timer
import kotlin.concurrent.schedule
class CoinTossActivity : AppCompatActivity() {
companion object {
fun getIntentCoin(context: Context) = Intent(context, CoinTossActivity::class.java)
}
private lateinit var binding: CoinTossActivityBinding
private var state0Count = 0
private var state1Count = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = CoinTossActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
initView()
}
private fun initView() = with(binding) {
var case: Int = 0
coinTossBackBtn.setOnClickListener {
finish()
}
val coinImageViews = arrayOf(
coinTossImgCoin1,
coinTossImgCoin2,
coinTossImgCoin3,
coinTossImgCoin4,
coinTossImgCoin5,
coinTossImgCoin6
)
//백버튼
coinTossImgBackArrow.setOnClickListener {
finish()
}
//하단 버튼 제어
tossBtn.setOnClickListener {
when (case) {
0 -> {
var soundPlayer: MediaPlayer? =
MediaPlayer.create(this@CoinTossActivity, R.raw.coin_effect)
soundPlayer?.start()
coinImageViews.forEach { coinToss(it) }
Timer().schedule(2500) {
runOnUiThread {
coinTossTvIsFront.visibility = View.VISIBLE
coinTossEtIsFront.visibility = View.VISIBLE
coinTossEtIsBack.visibility = View.VISIBLE
coinTossTvIsBack.visibility = View.VISIBLE
tossBtn.text = "Check the answer"
case = 1
}
}
}
1 -> {
coinImageViews.forEach { it.visibility = View.VISIBLE }
val answerFront = coinTossEtIsFront.text.toString() ?: "0"
val answerBack = coinTossEtIsBack.text.toString() ?: "0"
if (answerFront == state0Count.toString() && answerBack == state1Count.toString()) Toast.makeText(
this@CoinTossActivity,
"정답입니다",
Toast.LENGTH_SHORT
).show()
else Toast.makeText(
this@CoinTossActivity,
"오답입니다.",
Toast.LENGTH_SHORT
).show()
tossBtn.text = "Reset"
case = 2
}
2 -> {
coinTossTvIsFront.visibility = View.INVISIBLE
coinTossEtIsFront.visibility = View.INVISIBLE
coinTossEtIsFront.text = null
coinTossEtIsBack.visibility = View.INVISIBLE
coinTossEtIsBack.text = null
coinTossTvIsBack.visibility = View.INVISIBLE
state0Count = 0
state1Count = 0
coinImageViews.forEach { it.setImageResource(R.drawable.coin_front) }
tossBtn.text = "Coin Toss"
case = 0
}
}
}
}
private fun coinToss(view: ImageView) {
var state = 1
var animaition: Animation =
AnimationUtils.loadAnimation(this@CoinTossActivity, R.anim.coin_effect)
view.startAnimation(animaition)
Timer().schedule(2600) {
runOnUiThread {
view.visibility = View.INVISIBLE
state = (0..1).random()
when (state) {
0 -> {
view.setImageResource(R.drawable.coin_front)
state0Count++
}
1 -> {
view.setImageResource(R.drawable.coin_back)
state1Count++
}
}
}
}
}
}
여기서 처음 써본 것
runOnUiThread
이 것은 뷰에 직접적으로 딜레이를 주게되면 오류가 나게 되므로 주게 되는 UiThread다
이 부분을 잘 몰라서 앱이 죽는 것을 여러번 반복했다.
여기서 특이한점은 fun coinToss에서 Thread를 안줬는데도 작동을 하다가 중간에 죽었다는 것 이다.
그 이유는 튜터님하고 함께 원인규명을 해봤으나, 알 수 없었다.
도대체 왜 작동하면 안되는 로직이 작동했었을까?
2.viewtype 분기
package com.example.nbcamp_teamproject_call.contact
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.nbcamp_teamproject_call.databinding.ContactItem2Binding
import com.example.nbcamp_teamproject_call.databinding.ContactItemBinding
import com.example.nbcamp_teamproject_call.model.UserDB
import com.example.nbcamp_teamproject_call.model.UserModel
class ContactAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
const val VIEW_TYPE_1 = 1
const val ViEW_TYPE_2 = 2
}
private var list = mutableListOf<UserModel>()
private var viewType = VIEW_TYPE_1
fun setContactList(contactList: List<UserModel>) {
if (contactList.isEmpty()) return
list.addAll(contactList)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
VIEW_TYPE_1 -> {
ContactViewHolder(
ContactItemBinding.inflate(LayoutInflater.from(parent.context))
)
}
else -> {
Type2ViewHolder(
ContactItem2Binding.inflate(LayoutInflater.from(parent.context))
)
}
}
}
override fun getItemCount(): Int {
return UserDB.getInstance().size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = list[position]
when(viewType){
VIEW_TYPE_1 ->{
if (holder is ContactViewHolder) {
holder.onBind(item)
holder.setIsRecyclable(false)
}
}
else ->{
if (holder is Type2ViewHolder) {
holder.onBind(item)
holder.setIsRecyclable(false)
}
}
}
}
}
두 개의 뷰 분기를 위한 const val를 사용하여 현재 type상태를 판단할 수 있는 변수를 전역으로 선언하였다.
따라서 각 타입에 맞는 홀더 두 개를 따로 class를 만들어 생성한 다음에 넣어주었다.
다만 현재 문제가 있다.
onBindViewHolder
부분의 홀더가 제대로 작동하지 않는 이슈가 있다.
이에 대한 것을 고치는 중이다.
참고 블로그