I'm a beginner in kotlin
, but I know java
. So I've created a program, where I have one textview
. It will change it's test every 1sec with fade animation. So my program works fine, but as I'm beginner in kotlin
, can you help me or give a feedback related to my code. Also if I wrote something wrong, you can edit it without any problem :)
class MainActivity : AppCompatActivity() {
private lateinit var fadeInAnimation: Animation
private lateinit var fadeOutAnimation: Animation
private lateinit var handler: Handler
private lateinit var myRunnable: Runnable
private val textArray: Array<String> = arrayOf("This", "is", "fading", "text")
private var textPosition: Int = 0
companion object {
private const val ANIM_DURATION: Long = 1000L
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_in)
fadeOutAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_out)
handler = Handler()
initRunnable()
}
override fun onResume() {
super.onResume()
startAnimation()
}
override fun onPause() {
super.onPause()
stopAnimation()
}
private fun initRunnable() {
myRunnable = Runnable {
text_view.animation = fadeOutAnimation
fadeOutAnimation.start()
fadeOutAnimation.setAnimationListener(object : AnimationListener() {
override fun onAnimationEnd(animation: Animation?) {
textPosition = when (textPosition) {
textArray.size - 1 -> 0
else -> ++textPosition
}
startAnimation()
}
})
}
}
private fun startAnimation() {
text_view.text = textArray[textPosition]
text_view.animation = fadeInAnimation
fadeInAnimation.start()
handler.postDelayed(myRunnable, ANIM_DURATION)
}
private fun stopAnimation() {
handler.removeCallbacksAndMessages(null)
fadeInAnimation.cancel()
fadeOutAnimation.cancel()
}
}
Please leave feedback related to my code, how can I make it more clear, or maybe something I've done not right, or maybe something is not a practice? Thank you.
I would create one single animation in XML that does the fade in, delay, and fade out. Then you wouldn't need to use the handler to post the fade-out or juggle two animations. But since we're just looking at the Kotlin code:
postDelayed
extension function that swaps the argument order so you can use a trailing lambda. (You could alternatively store the Runnable in a val
so it's only instantiated once like in the comment from @Mostafa, but in my opinion it's trivially small and the code is clearer if you keep it at the location it's used.)textPosition
with the remainder operator (also would apply to Java).
private const val ANIM_DURATION: Long = 1000L
class MainActivity : AppCompatActivity() {
private lateinit var fadeInAnimation: Animation
private lateinit var fadeOutAnimation: Animation
private lateinit var handler: Handler
private val textArray: Array<String> = arrayOf("This", "is", "fading", "text")
private var textPosition: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_in)
fadeOutAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_out).apply {
setAnimationListener(object : AnimationListener() {
override fun onAnimationEnd(animation: Animation?) {
textPosition = (textPosition - 1 + textArray.size) % textArray.size
startAnimation()
}
})
}
handler = Handler()
}
override fun onResume() {
super.onResume()
startAnimation()
}
override fun onPause() {
super.onPause()
stopAnimation()
}
private fun startAnimation() {
text_view.text = textArray[textPosition]
text_view.animation = fadeInAnimation
fadeInAnimation.start()
handler.postDelayed(ANIM_DURATION) {
text_view.animation = fadeOutAnimation
fadeOutAnimation.start()
}
}
private fun stopAnimation() {
handler.removeCallbacksAndMessages(null)
fadeInAnimation.cancel()
fadeOutAnimation.cancel()
}
}
Also, if you define your animations using ObjectAnimator instead of the older Animations API, you can use doOnEnd
instead of the more clunky anonymous AnimationListener.