개발/Android
[프로젝트] 2일차 - 원판 만들고 돌리기
레란희
2021. 9. 9. 20:49
어제 만든 액티비티에 돌리기 버튼과 원판을 추가하였다.
원판은 View를 상속받은 Custom View를 만들었고
돌리기 버튼을 누르면 원판이 돌아가도록 하였다.
원판의 영역 갯수는 일단 고정적으로 3개만 주었고
돌릴 때의 시간이나 돌리는 각도는 랜덤으로 주었다.
1. 원판 만들기
RouletteView.kt
class RouletteView : View {
val COLORS = arrayOf(0xFFDDDDDD, 0xFFEEEEEE, 0xFFCCCCCC) //룰렛 구역에 들어갈 색상
val PAINTS = arrayOf(Paint(), Paint(), Paint()) //paint 객체를 미리 만들어두었다
var rectF: RectF? = null //원호를 그릴 때 쓰이는 RectF 객체를 미리 만들어두었다
//... 생성자
init {
for (i in PAINTS.indices) {
PAINTS[i].color = COLORS[i].toInt() //각 페인트는 구역 색상대로 칠해지도록 설정
}
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.let {
if (rectF == null) {
rectF = RectF(0f, 0f, width.toFloat(), height.toFloat()) //캔버스를 꽉 채우는 rectF 정의
}
for (i in PAINTS.indices) {
val sweepAngle = 360f / PAINTS.size //한번에 회전시킬 각도 = 한바퀴/갯수
val start = -90f + (i * sweepAngle) //12시 각도에서 시작하기 위해 -90에 돌릴 각도를 추가하였다
it.drawArc(rectF!!, start, sweepAngle, true, PAINTS[i]) //캔버스에 원호를 그림
}
}
}
별 것 없다 (....)
2. 원판 돌리기
다음으로 뷰를 돌려줄 roll 함수를 추가해주었다.
public fun roll() {
roll((Math.random() * 2000+900).toFloat())
}
public fun roll(degree: Float) {
rotation = 0f
val animation: ObjectAnimator = ObjectAnimator.ofFloat(this, "rotation", degree)
animation.duration = getRollDuration()
animation.interpolator = DecelerateInterpolator()
animation.start()
}
마찬가지로 별 것 없다 (.....)
이제 마지막으로 액티비티의 버튼을 눌렀을 때 처리를 해 준다.
MainActivity.kt
val rouletteView = findViewById<RouletteView>(R.id.roulette) //나는 레이아웃 뷰에서 룰렛 뷰를 추가해 뒀음.
findViewById<View>(R.id.btn_start).setOnClickListener {
rouletteView.roll() //룰렛을 돌린다
}
요렇게 하면 버튼을 누르면 원판이 돌아간다.
빙글빙글..
3. 원판 멈출 때 이벤트 처리
원판을 돌리는 것까진 했고, 원판이 멈췄을 때 어떤 액션을 취해주기 위해
OnRouletteListener 인터페이스를 만들고 추가해주었다.
OnRouletteListener.kt
interface OnRouletteListener {
fun onRouletteStop(position: Int) : Unit
}
RouletteView에 전역변수로 OnRouletteListener 객체를 선언하고
roll에 animationListener를 달아주고, 끝날 때 listener를 실행하도록 하였다.
RoulletView.kt의 roll(degree: Float) 메소드 내부
animation.addListener(object: Animator.AnimatorListener {
override fun onAnimationStart(p0: Animator?) {
TODO("Not yet implemented")
}
override fun onAnimationEnd(p0: Animator?) {
Log.i("TEST", "degree : $rotationX / $rotationY / $rotation");
listener?.onRouletteStop(0)
}
override fun onAnimationCancel(p0: Animator?) {
TODO("Not yet implemented")
}
override fun onAnimationRepeat(p0: Animator?) {
TODO("Not yet implemented")
}
})
그리고 MainActivity에서 listener를 정의해주었다.
MainActivity.kt
rouletteView.listener = object: OnRouletteListener {
override fun onRouletteStop(position: Int) {
Toast.makeText(this@MainActivity, "roullet stop", Toast.LENGTH_SHORT).show()
}
}