beginDelayedTransiton in RecyclerView ViewHolder is ignored - android

I am trying to animate RecyclerView items using ConstraintSet animation.
I have two layouts and they are switched properly using this code:
val constraint2 = ConstraintSet()
constraint2.clone(binding.root.context, R.layout.list_item_2)
val transition = ChangeBounds()
transition.interpolator = OvershootInterpolator(1.0f)
transition.duration = 1200
TransitionManager.beginDelayedTransition(binding.root.container, transition)
constraint2.applyTo(binding.root.container)
However delayed transition is completely ignored and it works the same way whether or not I add beginDelayedTransition code, so there is no animation.

Related

How to scroll a sync'd up MotionLayout+AppBarLayout programmatically?

Consider the following Coordinator+AppBar+MotionLayout and its MotionScene from Google's demo. This creates a MotionLayout that sync's its Transition progress when the user is scrolling.
Video Preview: https://i.imgur.com/1MnPB8R.mp4
However, I would like to do this in programmatically in Kotlin. Here are my failed attempts.
val motion = findViewById<MotionLayout>(R.id.constraintToolbar)
motion.transitionToState(R.id.end)
The above would cause the MotionLayout to animate, but would immediately blink back to the start state once finished. The AppBarLayout also does not change height.
val appbar = findViewById<AppBarLayout>(R.id.app_bar)
val scrollable = findViewById<NestedScrollView>(R.id.scrollable)
val s = if(motion.progress==0F) appbar.totalScrollRange else 0
scrollable.smoothScrollTo(0, s)
The above scrolls the NestedScrollView, but the AppBarLayout and MotionLayout does not receive the scroll events.
val s = if(motion.progress==0F)-appbar.totalScrollRange else 0
val appbar = findViewById<AppBarLayout>(R.id.app_bar)
appbar.scrollTo(0,s)
appbar.offsetTopAndBottom(s)
The above shifts the AppBarLayout, breaking the layout completely.
How do you trigger this scroll programmatically?
If there's only 2 states, you should try setExpanded()
val e = motion.progress != 0F
appbar.setExpanded(e, true)

Constraint layout setting runtime constraintStart_toEndOf

I have a constraint
app:layout_constraintStart_toStartOf="parent". Runtime I need to change this constraint to app:layout_constraintStart_toEndOf="#+id\myid" .
From my research i found only constraintSet.connect(viewid, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 50); . But how to achieve my requirements with this. Any idea on this?
This is in kotlin but it's barely different from Java.
Give an ID to the rootLayout.
Now, use this code:
val constraintSet = ConstraintSet()
constraintSet.clone(rootLayout) //Your rootLayout
constraintSet.connect(
yourView.id, //ID of the view whose position you want to change
ConstraintSet.START,
yourMyIdView.id, //ID of the correspondent view
ConstraintSet.END
)
constraintSet.applyTo(rootLayout) //Your rootLayout
ProTip : You can also animate the change by setting animateChange to true in rootLayout (XML) or you can use a Transition animation which I always prefer.
val transition: Transition = ChangeBounds()
transition.interpolator = AccelerateInterpolator() //Or Any other Interpolator
transition.duration = 700 //Duration
TransitionManager.beginDelayedTransition(rootLayout, transition) //Your rootLayout
constraintSet.applyTo(rootLayout) //Remember to put above 4 lines before this
You can further add Alpha animation it by using yourView.animate().alpha(1f).duration = 700 //1f (0 to 1) is the value and 700 is the duration.
Remember, it is barely different from Java, you just have to add ; at the end possibly.

ConstraintLayout by Code - Set Constraint too soon

Good day,
I need to show a list of fidelity cards, one on the others with a small border margin, and while clicking on it, it reveal it completely while sliding.
In a fragment, I use a ConstraintLayout somewhere in the screen that I populate by code.
I add all child's (total known after WS called) into the ConstraintLayout, then I am using ConstraintSet to set the initial constraints.
But at the initial fragment creation, I have found out that I must apply a TimeOut between the ConstraintLayout population and creating the Constraints (disgusting, right?)
adding each card...
val card = FrequencyCardView()
fid_card_container.addView(card as View)
listCard.add(card)
Then create the constraints:
val set = ConstraintSet()
val containerId = fid_card_container.id
set.clone(fid_card_container)
listCard.forEachIndexed { index, card ->
val marginTop = when (index) {
0 -> 0
else -> (listCard[index -1] as ViewGroup).height / 4
}
val rootId = if (index == 0) containerId else (index - 1)
set.connect(card.getId(), TOP, rootId, TOP, marginTop)
set.connect(card.getId(), ConstraintSet.START, containerId, ConstraintSet.START, 0)
set.connect(card.getId(), ConstraintSet.END, containerId, ConstraintSet.END, 0)
card.setOpen(false)
}
// Apply the changes
set.applyTo(fid_card_container)
Any idea, why I need to apply any timeout between adding the Childs into the ConstraintLayout and then add the Constraints?
Any better solution, that this ugly TimeOut?
Thanks
I have found a better way.
It seems that the constraints creation must be ensured to be done on the UI Thread. This is why it does work with the timeout.
So, I have changed the timeout call by the Anko call:
doAsync {
uiThread {
resetCardLayout()
}
}

Android Slide Trantition animation not working when using target

i want to crate animation from right to left when change activity, but not of window only certain layout, this is my code :
val transition = Slide()
transition.duration = 300
transition.slideEdge = Gravity.END
transition.mode = Visibility.MODE_IN
transition.interpolator = DecelerateInterpolator(2f)
transition.addTarget(R.id.ln_verification_phone)
window.enterTransition = transition
but when i remove transition.addTarget(R.id.ln_verification_phone), animation working but all of window, i want to target of view, are there wrong in my code, i try using exclude also not work

Enter animation using ConstraintSet

I'd like to make enter animation for activity using ConstraintSet, as it's shown in this video:
https://www.youtube.com/watch?v=OHcfs6rStRo.
The problem is I don't know in which lifecycle method to put code to make the transition visible to user.
In onCreate I'm calling:
setContentView(R.layout.layout_first_keyframe_detail);
topConstraintLayout = findViewById(R.id.top_constraint_layout);
constraintSet = new ConstraintSet();
constraintSet.clone(this, R.layout.layout_detail_top);
and then I'd like to call:
TransitionManager.beginDelayedTransition(topConstraintLayout);
constraintSet.applyTo(topConstraintLayout);
when activity is already visible. Unfortunately I don't find any lifecycle method to do this.
If you look at TransitionManager.beginDelayedTransiton() implementation, you will see that it starts with following check :
if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut())
Looking at isLaidOut() documentation will make you understand that the view has to be drawn at least once so the animation can be executed :
Returns true if this view has been through at least one layout since
it was last attached to or detached from a window.
However, wrapping the animation launch in a message worked for me. So you should try to do it like :
myView.post{
TransitionManager.beginDelayedTransition(topConstraintLayout);
constraintSet.applyTo(topConstraintLayout);
}
to create animations using ConstraintLayout and ConstraintSet you must first consider that there must be a starting layout and an ending layout
Step 1: Create your layouts
create your starting layout and ending layout as you want
--> suppose the starting layout name is (activity) the ending layout name is (activity_alt)
Step 2: Create Animation
now in the MainActivity inside onCreate method call your function foo
private void foo() {
var set = false
val constraint1 = ConstraintSet()
constraint1.clone(root)
val constraint2 = ConstraintSet()
constraint2.clone(this, R.layout.activity_alt)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
TransitionManager.beginDelayedTransition(root)
val constraint = if(set) constraint1 else constraint2
constraint.applyTo(root)
set = !set
}
}

Categories

Resources