Commit d0276422 by likorn

Timing is now managed by TimerFragment

parent 18d8b0b0
package com.paktalin.quickmax
import android.animation.ArgbEvaluator
import android.animation.ValueAnimator
import android.content.Intent
import android.graphics.Color
import android.graphics.PorterDuff
import android.os.Bundle
import android.os.CountDownTimer
import android.util.TypedValue
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.commit
import com.paktalin.quickmax.answers.Answer
import com.paktalin.quickmax.answers.AnswerSet
import kotlinx.android.synthetic.main.activity_task.*
......@@ -17,19 +10,23 @@ import kotlinx.android.synthetic.main.activity_task.*
// TODO save state
class TaskActivity : AppCompatActivity() {
internal lateinit var answerSet: AnswerSet
private lateinit var answerSet: AnswerSet
private var millisToSolve: Long = 4000
private var numDigits: Int = 3
private lateinit var timer: CountDownTimer
private lateinit var colorAnimation: ValueAnimator
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task)
btn_back.setOnClickListener { startActivity(Intent(this@TaskActivity, MainActivity::class.java)) }
btn_back.setOnClickListener {
startActivity(
Intent(
this@TaskActivity,
MainActivity::class.java
)
)
}
retrieveExtras()
initTimer()
startNewRound()
}
......@@ -47,9 +44,9 @@ class TaskActivity : AppCompatActivity() {
numDigits,
listOf(card_left_top, card_right_top, card_left_bottom, card_right_bottom)
)
addTimerFragment(supportFragmentManager, millisToSolve)
setUpCards()
timer.start()
startColorAnimation()
removeButtonNextFragment(supportFragmentManager)
}
private fun retrieveExtras() {
......@@ -59,63 +56,28 @@ class TaskActivity : AppCompatActivity() {
private fun setUpCards() {
answerSet.forEach { answer ->
answer.card.setOnCheckedChangeListener { _, isChecked -> if (isChecked) processAnswer(answer) }
answer.card.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) processAnswer(answer)
}
answer.card.initial(this@TaskActivity, answer.value)
}
}
private fun processAnswer(answer: Answer) {
timer.cancel()
colorAnimation.cancel()
setResponseText(answer)
answerSet.forEach { answer -> answer.card.disable()}
}
private fun setResponseText(answer: Answer) {
tv_response.setTextSize(TypedValue.COMPLEX_UNIT_SP, resources.getDimension(R.dimen.response_text_size))
if (answer.correct) {
answer.card.markCorrect(this@TaskActivity)
tv_response.text = resources.getString(R.string.response_correct)
supportFragmentManager.commit(true) {
add(R.id.main_layout, ButtonNextFragment().apply { arguments = Bundle().apply { putBoolean("correct", true) } })
}
(supportFragmentManager.findFragmentByTag("timer_fragment") as TimerFragment).cancelCorrect()
addButtonNextFragment(supportFragmentManager, true)
} else {
answer.card.markWrong(this@TaskActivity)
tv_response.text = resources.getString(R.string.response_wrong)
supportFragmentManager.commit(true) {
add(R.id.main_layout, ButtonNextFragment().apply { arguments = Bundle().apply { putBoolean("correct", false) } })
}
(supportFragmentManager.findFragmentByTag("timer_fragment") as TimerFragment).cancelWrong()
addButtonNextFragment(supportFragmentManager, false)
}
answerSet.forEach { answer -> answer.card.disable() }
}
private fun startColorAnimation() {
val colorFrom = Color.TRANSPARENT
val colorTo = color(this, R.color.transparent_red)
colorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)
.apply { duration = millisToSolve }
colorAnimation.addUpdateListener { animator ->
layout_gradient.background.setColorFilter(animator.animatedValue as Int,
PorterDuff.Mode.SRC_ATOP)
}
colorAnimation.start()
}
private fun initTimer() {
timer = object : CountDownTimer(millisToSolve, 1000) {
override fun onTick(millisUntilFinished: Long) {
tv_response.text = (millisUntilFinished/1000).toString()
}
override fun onFinish() {
tv_response.setTextSize(TypedValue.COMPLEX_UNIT_SP, resources.getDimension(R.dimen.response_text_size))
tv_response.text = resources.getString(R.string.time_is_over)
supportFragmentManager.commit(true) {
add(R.id.main_layout, ButtonNextFragment().apply { arguments = Bundle().apply { putBoolean("correct", false) } })
}
answerSet.forEach { answer -> answer.card.disable()}
}
}
fun onTimeOver() {
addButtonNextFragment(supportFragmentManager, false)
answerSet.forEach { answer -> answer.card.disable() }
}
}
package com.paktalin.quickmax
import android.animation.ArgbEvaluator
import android.animation.ValueAnimator
import android.graphics.Color
import android.graphics.PorterDuff
import android.os.Bundle
import android.os.CountDownTimer
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
class TimerFragment: Fragment() {
private lateinit var timer: CountDownTimer
private var millisToSolve: Long = 0
private val interval: Long = 1000
private lateinit var tvResponse: TextView
private lateinit var colorAnimation: ValueAnimator
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
millisToSolve = arguments!!.getLong("millis_to_solve")
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.gradient_timer, container, false)
tvResponse = view!!.findViewById(R.id.tv_response)
initTimer()
initColorAnimation()
return view
}
override fun onStart() {
super.onStart()
timer.start()
colorAnimation.start()
}
fun cancelCorrect() {
cancel()
tvResponse.text = resources.getString(R.string.response_correct)
}
fun cancelWrong() {
cancel()
tvResponse.text = resources.getString(R.string.response_wrong)
}
private fun cancel() {
timer.cancel()
colorAnimation.cancel()
tvResponse.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize(resources) )
}
private fun initTimer() {
timer = object : CountDownTimer(millisToSolve, interval) {
override fun onTick(millisUntilFinished: Long) {
tvResponse.text = (millisUntilFinished / interval).toString()
}
override fun onFinish() {
tvResponse.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize(resources) )
tvResponse.text = resources.getString(R.string.time_is_over)
(activity as TaskActivity).onTimeOver()
}
}
}
private fun initColorAnimation() {
val colorFrom = Color.TRANSPARENT
val colorTo = color(context!!, R.color.transparent_red)
colorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)
.apply { duration = millisToSolve }
colorAnimation.addUpdateListener { animator ->
view!!.background.setColorFilter(animator.animatedValue as Int, PorterDuff.Mode.SRC_ATOP)
}
}
}
\ No newline at end of file
package com.paktalin.quickmax
import android.content.Context
import android.content.res.Resources
import android.os.Bundle
import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.commit
import com.google.android.material.card.MaterialCardView
fun getTextView(card: View): TextView {
......@@ -13,4 +17,33 @@ fun getTextView(card: View): TextView {
fun color(context: Context, id: Int): Int {
return ContextCompat.getColor(context, id)
}
fun textSize(resources: Resources): Float {
val screenDensity = resources.displayMetrics.density
return resources.getDimension(R.dimen.response_text_size) / screenDensity
}
fun addTimerFragment(supportFragmentManager: FragmentManager, millisToSolve: Long) {
val timerFragment = TimerFragment().apply {
arguments = Bundle().apply { putLong("millis_to_solve", millisToSolve) }
}
supportFragmentManager.commit(true) {
replace(R.id.fragment_timer, timerFragment, "timer_fragment")
}
}
fun addButtonNextFragment(supportFragmentManager: FragmentManager, correct: Boolean) {
val fragmentBtnNext = ButtonNextFragment().apply {
arguments = Bundle().apply { putBoolean("correct", correct) }
}
supportFragmentManager.commit(true) {
add(R.id.main_layout, fragmentBtnNext, "btn_next_fragment")
}
}
fun removeButtonNextFragment(supportFragmentManager: FragmentManager) {
supportFragmentManager.findFragmentByTag("btn_next_fragment")?.let {fragment ->
supportFragmentManager.commit(true) { remove(fragment) }
}
}
\ No newline at end of file
......@@ -46,9 +46,11 @@
android:text="@string/response_correct"
android:textColor="@android:color/white"
android:textSize="60sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/cv_task"
app:layout_constraintStart_toStartOf="@+id/cv_task"
app:layout_constraintTop_toTopOf="@+id/layout_answers"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.25"
app:layout_constraintVertical_chainStyle="spread" />
<com.google.android.material.card.MaterialCardView
......
......@@ -8,16 +8,15 @@
android:background="#DADADA"
tools:context="com.paktalin.quickmax.TaskActivity">
<View
android:id="@+id/layout_gradient"
<FrameLayout
android:id="@+id/fragment_timer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="32dp"
android:background="@drawable/gradient"
app:layout_constraintBottom_toBottomOf="@+id/cv_task"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="32dp" />
<ImageButton
android:id="@+id/btn_back"
......@@ -31,20 +30,6 @@
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_back" />
<TextView
android:id="@+id/tv_response"
style="@style/TextAppearance.MaterialComponents.Headline4"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="2dp"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="60sp"
app:layout_constraintBottom_toTopOf="@+id/cv_task"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/cv_task"
android:layout_width="0dp"
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/gradient"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_response"
style="@style/TextAppearance.MaterialComponents.Headline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="2dp"
android:gravity="center"
android:text="@string/response_correct"
android:textColor="@android:color/white"
android:textSize="60sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.4" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="response_text_size">14sp</dimen>
<dimen name="response_text_size">40sp</dimen>
</resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment