11package com.willowtreeapps.namegame.store
22
3- import android.animation.Animator
4- import android.animation.AnimatorListenerAdapter
53import android.animation.AnimatorSet
64import android.animation.ObjectAnimator
75import android.graphics.Color
@@ -15,29 +13,27 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
1513import com.willowtreeapps.common.QuestionViewState
1614import com.willowtreeapps.common.ui.QuestionView
1715import kotlinx.android.synthetic.main.fragment_question.*
18- import kotlinx.coroutines.CoroutineScope
19- import kotlinx.coroutines.Dispatchers
2016import nl.dionsegijn.konfetti.models.Shape
2117import nl.dionsegijn.konfetti.models.Size
22- import java.lang.IllegalStateException
2318import kotlin.coroutines.CoroutineContext
2419import android.widget.Button
25- import androidx.annotation.ColorRes
20+ import androidx.core.content.res.ResourcesCompat
21+ import androidx.interpolator.view.animation.FastOutSlowInInterpolator
2622import com.willowtreeapps.common.ui.QuestionPresenter
2723import com.willowtreeapps.namegame.*
24+ import kotlinx.coroutines.*
2825
2926
3027class QuestionFragment : Fragment (), CoroutineScope, QuestionView, MainActivity.IOnBackPressed {
3128
32- private var presenter: QuestionPresenter ? = null
29+ private lateinit var presenter: QuestionPresenter
3330
3431 override val coroutineContext: CoroutineContext
3532 get() = Dispatchers .Main
3633
3734 private var restoreX: Float? = null
3835 private var restoreY: Float? = null
39- @ColorRes
40- var lastCorrectBtn: Button ? = null
36+ private var lastCorrectBtn: Button ? = null
4137 private var lastSelectedBtn: Button ? = null
4238
4339 override fun onCreateView (inflater : LayoutInflater , container : ViewGroup ? , savedInstanceState : Bundle ? ): View ? {
@@ -51,26 +47,26 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
5147
5248 override fun onPause () {
5349 super .onPause()
54- NameGameApp .gameEngine().detachView(presenter !! )
50+ NameGameApp .gameEngine().detachView(this )
5551 }
5652
5753 override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) {
5854 initViews()
5955 }
6056
6157 private fun initViews () {
62- button1.setOnClickListener { presenter? .namePicked(button1.text.toString()) }
63- button2.setOnClickListener { presenter? .namePicked(button2.text.toString()) }
64- button3.setOnClickListener { presenter? .namePicked(button3.text.toString()) }
65- button4.setOnClickListener { presenter? .namePicked(button4.text.toString()) }
66- btn_next.setOnClickListener { presenter? .nextTapped() }
67- btn_end_game.setOnClickListener { presenter? .endGameTapped() }
58+ button1.setOnClickListener { presenter.namePicked(button1.text.toString()) }
59+ button2.setOnClickListener { presenter.namePicked(button2.text.toString()) }
60+ button3.setOnClickListener { presenter.namePicked(button3.text.toString()) }
61+ button4.setOnClickListener { presenter.namePicked(button4.text.toString()) }
62+ btn_next.setOnClickListener { presenter.nextTapped() }
63+ btn_end_game.setOnClickListener { presenter.endGameTapped() }
6864 }
6965
7066
7167 override fun onBackPressed (): Boolean {
72- NameGameApp .gameEngine().detachView(presenter !! )
73- presenter? .onBackPressed()
68+ NameGameApp .gameEngine().detachView(this )
69+ presenter.onBackPressed()
7470 return false
7571 }
7672
@@ -82,25 +78,16 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
8278 setProfileAndFadeIn(viewState)
8379 }
8480 }
85- }
86-
87-
88- override fun showCorrectAnswer (viewState : QuestionViewState ) {
89- hideButtonsShowNext(viewState, false )
90- celebrate()
91- }
9281
93- override fun showWrongAnswer (viewState : QuestionViewState ) {
94- wrongShakeAnimation(viewState) { hideButtonsShowNext(viewState, false ) }
9582 }
9683
97- override fun showCorrectAnswerEndGame (viewState : QuestionViewState ) {
98- hideButtonsShowNext(viewState, true )
84+ override fun showCorrectAnswer (viewState : QuestionViewState , isEndGame : Boolean ) {
85+ hideButtonsShowNext(viewState, isEndGame )
9986 celebrate()
10087 }
10188
102- override fun showWrongAnswerEndGame (viewState : QuestionViewState ) {
103- wrongShakeAnimation(viewState) { hideButtonsShowNext(viewState, true ) }
89+ override fun showWrongAnswer (viewState : QuestionViewState , isEndGame : Boolean ) {
90+ wrongShakeAnimation(viewState) { hideButtonsShowNext(viewState, isEndGame ) }
10491 }
10592
10693 private val showButtonsAnimatorSet by lazy {
@@ -115,19 +102,19 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
115102
116103 private fun wrongShakeAnimation (viewState : QuestionViewState , after : () -> Unit ) {
117104 val selectedBtn = getBtnByNum(viewState.selectedBtnNum)
118- selectedBtn.isSelected = true
119- val animScaleX = ObjectAnimator .ofFloat(selectedBtn, View . SCALE_X , 3F , 0.5F , 1F )
120- val animScaleY = ObjectAnimator .ofFloat(selectedBtn, View .SCALE_Y , 3F , 0.5F , 1F )
121- val upSet = AnimatorSet ( )
122- upSet.playTogether(animScaleX, animScaleY )
123- upSet.interpolator = BounceInterpolator ( )
124- upSet.duration = 500
125- upSet.addListener( object : AnimatorListenerAdapter () {
126- override fun onAnimationEnd ( animation : Animator ? ) {
127- after ()
128- }
129- } )
130- upSet.start()
105+ if ( selectedBtn != null ) {
106+ selectedBtn.isSelected = true
107+ val animScaleX = ObjectAnimator .ofFloat(selectedBtn, View .SCALE_X , 3F , 0.5F , 1F )
108+ val animScaleY = ObjectAnimator .ofFloat(selectedBtn, View . SCALE_Y , 3F , 0.5F , 1F )
109+ val upSet = AnimatorSet ( )
110+ upSet.playTogether(animScaleX, animScaleY )
111+ upSet.interpolator = BounceInterpolator ()
112+ upSet.duration = 500
113+ upSet.onComplete { after() }
114+ upSet.start ()
115+ } else {
116+ after( )
117+ }
131118 }
132119
133120 /* *
@@ -157,8 +144,8 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
157144 set
158145 }
159146 }
160- restoreX = correctBtn.x
161- restoreY = correctBtn.y
147+ restoreX = correctBtn? .x
148+ restoreY = correctBtn? .y
162149 lastCorrectBtn = correctBtn
163150 lastSelectedBtn = selectedBtn
164151
@@ -170,15 +157,15 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
170157 val set = AnimatorSet ()
171158 set.playTogether(anim1, anim2, anim3, anim4)
172159 set.onComplete {
173- val btn = if (isEndGame) {
174- btn_end_game
175- } else {
176- btn_next
177- }
178- btn.visibility = View .VISIBLE
179- btn.alpha = 0F
180- btn.animate().alpha(1f )
160+ val btn = if (isEndGame) {
161+ btn_end_game
162+ } else {
163+ btn_next
181164 }
165+ btn.visibility = View .VISIBLE
166+ btn.alpha = 0F
167+ btn.animate().alpha(1f )
168+ }
182169 set.start()
183170 }
184171
@@ -194,26 +181,72 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
194181 }
195182
196183 private fun fadeNextButton (after : () -> Unit ) {
197- btn_next.animate().alpha(0f ).setListener(object : AnimatorListenerAdapter () {
198- override fun onAnimationEnd (animation : Animator ? ) {
199- btn_next.visibility = View .GONE
200- after()
201- btn_next.animate().setListener(null )
202- }
203- })
184+ btn_next.animate().alpha(0f ).withEndAction {
185+ btn_next.visibility = View .GONE
186+ after()
187+ }
204188 }
205189
206190 private fun setProfileAndFadeIn (viewState : QuestionViewState ) {
207191 with (viewState) {
208192 txt_results.text = title
209193 GlideApp .with (this @QuestionFragment).load(profileImageUrl)
210194 .transition(DrawableTransitionOptions .withCrossFade())
195+ .onComplete {
196+ showButtons()
197+ txt_timer.visibility = View .VISIBLE
198+ presenter.profileImageIsVisible()
199+ }
211200 .into(imageView)
212201 button1.text = button1Text
213202 button2.text = button2Text
214203 button3.text = button3Text
215204 button4.text = button4Text
216- showButtons()
205+ }
206+ }
207+
208+ override fun setTimerText (viewState : QuestionViewState ) {
209+ activity?.runOnUiThread {
210+ txt_timer.scaleX = 0f
211+ txt_timer.scaleY = 0f
212+ txt_timer.alpha = 1f
213+ txt_timer.text = viewState.timerText
214+ txt_timer.animate()
215+ .scaleX(1f )
216+ .scaleY(1f )
217+ .setInterpolator(FastOutSlowInInterpolator ())
218+ .setDuration(500 )
219+ .withEndAction {
220+ if (txt_timer != null ) {
221+ txt_timer.animate()
222+ .scaleX(0f )
223+ .scaleY(0f )
224+ .duration = 500
225+ }
226+ }
227+ }
228+ }
229+
230+ override fun showTimesUp (viewState : QuestionViewState , isEndGame : Boolean ) {
231+ activity?.runOnUiThread {
232+ txt_timer.scaleX = 0f
233+ txt_timer.scaleY = 0f
234+ txt_timer.text = viewState.timerText
235+ val restoreColor = txt_timer.currentTextColor
236+ txt_timer.setTextColor(ResourcesCompat .getColor(context?.resources!! , R .color.red, null ))
237+ txt_timer.animate()
238+ .scaleX(1f )
239+ .scaleY(1f )
240+ .setInterpolator(FastOutSlowInInterpolator ())
241+ .setDuration(500 )
242+ .withEndAction {
243+ showWrongAnswer(viewState, isEndGame)
244+ txt_timer.animate().alpha(0f )
245+ .withEndAction {
246+ txt_timer.visibility = View .VISIBLE
247+ txt_timer.setTextColor(restoreColor) }
248+ }
249+
217250 }
218251 }
219252
@@ -230,12 +263,12 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
230263 .burst(200 )
231264 }
232265
233- private fun getBtnByNum (num : Int ): Button = when (num) {
266+ private fun getBtnByNum (num : Int ): Button ? = when (num) {
234267 1 -> button1
235268 2 -> button2
236269 3 -> button3
237270 4 -> button4
238- else -> throw IllegalStateException (" Invalid correct button index" )
271+ else -> null // throw IllegalStateException("Invalid button index")
239272 }
240273
241274
0 commit comments