So I was trying animation on Android using View Binding and it was not working, I tried the old way of getting views (findViewById()) and it happened to work just fine. Any answer to why View Binding doesn't work with animations? Thanks in advance for any answer. Here the example code:
activity_main.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/sopint_background"
tools:context=".MainActivity">
<TextView
android:id="@ id/tvLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/rectangle_bordered"
android:fontFamily="@font/aldrich"
android:lineSpacingExtra="12sp"
android:padding="20dp"
android:text="I am a text"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
logo_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="2000"
android:fromXDelta="0%"
android:fromYDelta="-50%" />
<alpha
android:duration="1500"
android:fromAlpha="0.1"
android:toAlpha="1.0" />
</set>
and MainActivity.kt
class MainActivity : AppCompatActivity() {
//Binding
lateinit var binding: ActivityMainBinding
//Variables
lateinit var topAnimation: Animation
lateinit var logo: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setContentView(R.layout.activity_main)
logo = findViewById(R.id.tvLogo)
topAnimation = AnimationUtils.loadAnimation(applicationContext, R.anim.logo_animation)
logo.startAnimation(topAnimation)
//This does not work
//binding.tvLogo.startAnimation((topAnimation))
}
}
CodePudding user response:
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setContentView(R.layout.activity_main)
What you're doing here is
- inflating a layout, storing it in
binding
- displaying that inflated layout
- replacing that and displaying another inflated copy of the layout
binding.tvLogo.startAnimation((topAnimation))
This doesn't work because you can't see it happening - you're animating the View
on the first layout you inflated, but it's the second one that's being displayed, and you're not interacting with that.
logo = findViewById(R.id.tvLogo)
logo.startAnimation(topAnimation)
Whereas this one works because you're looking up tvLogo
on the currently displayed layout (the second one) and then animating that View
. Because it's the one on the screen, you see the results
Basically, if you ever find yourself inflating a layout more than once, that's a sign you're doing something wrong (there can be situations where you would, but in that case you'd know why you're doing it!). And the same goes for multiple setContentView
calls