I'm trying to set visibility of a view to GONE after set its alpha to zero :
view.animate()
.alpha(0.0f)
.setDuration(500)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
view.visibility= GONE
}
})
But animation shows twice. In the other words, my view shows and hides again after calling view.visibility= GONE.
Any ideas?
My mistake was adding android:animateLayoutChanges="true" in the root of layout. It animates my view again!
When you are using this view animation there is a method which is withEndAction which takes a runnable and with lambda it looks something like this :
view.animate()
.alpha(0.0f)
.setDuration(500).withEndAction{
view.alpha = 0.0f
view.visibility= GONE
}
Try this.
Hope this helps.
Related
I have 3 buttons that has the same animation.
let's call them, button1, button2, button3.
button1
.animate()
.setDuration(initialTime)
.setInterpolator(DecelerateInterpolator())
.alpha(1f)
.start()
button2
.animate()
.setDuration(initialTime)
.setInterpolator(DecelerateInterpolator())
.alpha(1f)
.start()
button3
.animate()
.setDuration(initialTime)
.setInterpolator(DecelerateInterpolator())
.alpha(1f)
.start()
But this is too long. I need something like...
with(button1+button2+button3).apply{
this.animate()
.setDuration(initialTime)
.setInterpolator(DecelerateInterpolator())
.alpha(1f)
.start()
}
This will be clearer and simpler.
I could make a list of the views but this method is also longer and massier.
Is there any features like that in Kotlin?
val buttons = listOf(button1, button2, button3)
buttons.forEach {
it.animate()
.setDuration(initialTime)
.setInterpolator(DecelerateInterpolator())
.alpha(1f)
.start()
}
extension function
fun Button.setUp() {
this.animate()
.setDuration(initialTime)
.setInterpolator(DecelerateInterpolator())
.alpha(1f)
.start()
}
button1.setUp()
button2.setUp()
button3.setUp()
What I am trying to do is retrieve data from the server when I click a button. When I click the button, I want to show my "Loading..." TextView for 2 seconds, and only then show the data I got from the server. How can I do this?
For now my animation is working, but the data is showing almost instantly. I want to delay that. Using Thread.sleep(2000) causes both the data and Loading to be delayed.
val loadingAnimation :TextView = findViewById<TextView>(R.id.loadingAnimationTextView)
val alphaAnim = AlphaAnimation(1.0f, 0.0f)
alphaAnim.startOffset = 0
alphaAnim.duration = 2000
alphaAnim.setAnimationListener(object : AnimationListener {
override fun onAnimationRepeat(animation: Animation?) {
//not sure what code to put here
}
override fun onAnimationEnd(animation: Animation) {
// make invisible when animation completes, you could also remove the view from the layout
loadingAnimation.setVisibility(View.INVISIBLE)
}
override fun onAnimationStart(animation: Animation?) {
loadingAnimation.setVisibility(View.VISIBLE)
}
})
loadingAnimation.setAnimation(alphaAnim)
Thread.sleep(2000)
You can use the handler for this task.
Handler(Looper.getMainLooper()).postDelayed({
// Show you data here
loadingAnimation.setVisibility(View.INVISIBLE)
}, 2000)
Here, 2000 = 2 seconds
It's probably easier to use the ViewPropertyAnimator stuff:
loadingAnimation.animate()
.alpha(0)
.duration(2000)
.withEndAction {
// data displaying code goes here
}.start()
but honestly I don't think there's anything wrong with populating an invisible list, and just making it visible when you want to display it. But that up there is a way to chain runnable code and animations, one after the other
I have a simple fade out animation function for my android app, it works, but the issue I am having is that, after the fade out animation has run, the view (TextView in this case) does not stay faded out, the alpha value becomes 1 again.
Here is the fadeOut function code:
fun fadeOut(duration: Long = 100) : AlphaAnimation{
val fadeOut = AlphaAnimation(1f, 0f)
fadeOut.interpolator = DecelerateInterpolator()
fadeOut.duration = duration
return fadeOut
}
And I use it like this:
myTextView.startAnimation(fadeOut(500))
Any help or advice will be highly appreciated.
I think Animation::setFillAfter function would do the trick for you, the code would be like this:
val animation = fadeOut(500)
animation.fillAfter = true
myTextView.startAnimation(animation)
Although, this solution only preserves the alpha value of the view after the animation ends, if you want to change the visibility of the view, you need to change it when the animation ends using Animation.AnimationListener interface, the code would be like this:
myTextView.startAnimation(fadeOut(500).apply {
setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation?) {
}
override fun onAnimationEnd(animation: Animation?) {
myTextView.visibility = View.GONE
}
override fun onAnimationRepeat(animation: Animation?) {
}
})
})
You can set visibility in handler after running animation
myTextView.startAnimation(fadeOut(500))
Handler().postDelayed({
myTextView.visibility = View.GONE
},500)
I build Android apps using the MVP pattern and I'm often breaking up my UI into various sections like this:
<ConstraintLayout
android:id="#+id/recyclerSection"
<ConstraintLayout
android:id="#+id/errorSection"
<ConstraintLayout
android:id="#+id/emptySection"
Then in my presenter I'll call
view.showError()
and my view ends up with functions that look like this:
override fun showError(){
recyclerSection.visibility = View.GONE
errorSection.visibility = View.VISIBLE
emptySection.visibility = View.GONE
}
override fun showList(){
recyclerSection.visibility = View.VISIBLE
errorSection.visibility = View.GONE
emptySection.visibility = View.GONE
}
Is there a more elegant way to code this to achieve this toggling of view sections?
What do you mean with elegant? Here's an fade extension which is pretty nice
fun View.fadeToVisible(time: Long) {
alpha = 0f
animate()
.alpha(1f)
.setDuration(time)
.withStartAction {
visibility = View.VISIBLE
}
.start()
}
fun View.fadeToGone(time: Long) {
alpha = 1f
animate()
.alpha(0f)
.setDuration(time)
.withEndAction {
visibility = View.GONE
}
.start()
}
And then you use it like this (with 200 ms time):
override fun showError(){
recyclerSection.fadeToGone(200)
errorSection.fadeToVisible(200)
emptySection.fadeToGone(200)
}
override fun showList(){
recyclerSection.fadeToVisible(200)
errorSection.fadeToGone(200)
emptySection.fadeToGone(200)
}
However it's a matter of taste :)
I am trying to move Imageview in curved path to a particular point. So I make use of this library. I have to move the imageview in the curved path and the image view should return to its original position. This is one cycle. But it should repeat indefinitely until I press a button in that activity.
It works as expected but when the imageview finishes one cycle and about to start the next cycle, the image view is shaken little bit at the starting point (This is not happening for the first time but it happens for second and so forth) and then the animation proceeds normally.
private fun startAnimation(thermView: ImageView, thermAnimIdentifierView: TextView) {
Log.d(TAG, "****************************************************Start Animation")
val arcAnimator = ArcAnimator.createArcAnimator(thermView, thermAnimIdentifierView, 360f, Side.RIGHT)
arcAnimator.setDuration(5000)
arcAnimator.setInterpolator(CycleInterpolator(0.5f))
arcAnimator.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
}
override fun onAnimationEnd(animation: Animator) {
val arcAnimator = ArcAnimator.createArcAnimator(thermView, thermAnimIdentifierView, 360f, Side.RIGHT)
arcAnimator.setStartDelay(500)
arcAnimator.setDuration(5000)
arcAnimator.setInterpolator(CycleInterpolator(0.5f))
arcAnimator.addListener(this)
arcAnimator.start()
}
override fun onAnimationCancel(animation: Animator) {
}
override fun onAnimationRepeat(animation: Animator) {
}
})
arcAnimator.start()
}