Prevent Views From Being Clicked Until Animation Added To Action Via Navigation Component Completes
Solution 1:
You can start by having your views as disabled in xml android:enabled="false"
then in your fragment's onViewCreated
you can set a delay
with the animation duration using coroutines:
overridefunonViewCreated(view: View, savedState: Bundle?) {
super.onViewCreated(view, savedState)
// Initialize views here.
lifecycleScope.launch {
delay(resources.getInteger(R.integer.anim_duration).toLong())
// Enable views here
myView.isEnabled = true
}
}
Solution 2:
While I originally solved the problem using coroutines I faced the same problem once again :] so I investigated a bit and stumbled upon this topic Disable clicks when fragment adding animation playing that helped me to figure out the right solution.
Apparently those action animations added through the navigation graph are
set by FragmentTransaction.setCustomAnimation(enter, exit, popEnter, popExit)
and these can be accessed by overriding onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int)
. Where nextAnim
actually represents the action animations we added. For the fragment A
it would be either exit
or popEnter
and for the fragment B
it would be either enter
or popExit
.
The problem of views being clicked happens when fragment is entering (either enter
or popEnter
) so one can use an if statement to check enter
and if true
create Animation
based on the nextAnim
and then one can set listener to it. In case of home (starting) fragment one should exclude the case of nextAnim = 0
since it's also entering animation.
overridefunonCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (nextAnim == 0 || !enter) returnsuper.onCreateAnimation(transit, enter, nextAnim)
else {
return AnimationUtils.loadAnimation(requireContext(), nextAnim).apply {
setAnimationListener(object : Animation.AnimationListener {
overridefunonAnimationStart(animation: Animation?) {
disableClicking()
}
overridefunonAnimationEnd(animation: Animation?) {
enableClicking()
}
overridefunonAnimationRepeat(animation: Animation?) {
}
})
}
}
}
EDIT: For non-home fragments to avoid disabling clicks at the start of the animation, we can start with views being unclickable in xml layout and only enable clicking when the animation ends. To remove a bug where views remain unclickable if a device rotation happens we can introduce a boolean
variable that we will set to true
when animation ends and preserve it by overriding onSaveInstanceState(outState: Bundle)
and reinstating it in onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?)
and check if it was true
before device rotation to re-enable clicking once again.
Post a Comment for "Prevent Views From Being Clicked Until Animation Added To Action Via Navigation Component Completes"