Shrink/Grow layout w/ animation on DialogFragment - android

I have a DialogFragment I'm trying to animate so that when onClick()'ed a confirmation appears underneath.
I have tried using setVisibility() with an Animator, but that isn't what I'm looking for. I want the layout to Slide In with the animation not appear after, or conversely disappear before.
I have been playing with some code from Github here https://github.com/ThePreviousOne/Example
`
handle.setOnClickListener( new View.OnClickListener() {
float startHeight;
#Override
public void onClick(View v) {
startHeight = slideDownView.getHeight();
// Adjust the slide down height immediately with touch movements.
if (down) {
LayoutParams params = slideDownView.getLayoutParams();
params.height = (int) (startHeight - 300);
slideDownView.setLayoutParams(params);
down = false;
} else {
LayoutParams params = slideDownView.getLayoutParams();
params.height = (int) (startHeight + 300);
slideDownView.setLayoutParams(params);
down = true;
}
}
});
This works but I dont know how to connect the new code to an animator so I can control the speed the fragment resizes at

You can define a custom animator that updates the height property at each frame of the animation. For example:
int startHeight = slideDownView.getHeight();
// Note that you should not hardcode "300" as that will be different pixel values on
// different devices - get the value from a dimen resource or scale by the
// device density
int endHeight = startHeight - getDistanceToAnimate();
// Create a simple int animator that animates between the starting and ending height
ValueAnimator animator = ValueAnimator.ofInt(startHeight, endHeight);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// On each frame, update the view height
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = value;
view.setLayoutParams(layoutParams);
}
#Override
public void onAnimationEnd(Animator animation) {
// Once the animation finishes, you might have to update the view's final
// height and / or its `layout_height` attribute.
}
});
animator.setDuration(getAnimationTime());
animator.start();
Hope that helps!

Related

Expanding animation on view with Nine-Patch as background

I'm trying to create an animation that expands a View from top to bottom.
Like this:
I can't use a ScaleAnimation with pivotY set to 0 because this stretches the Nine-Patch like a normal Bitmap. I need to modify the height of my View.
My current solution: (test is the View reference)
ValueAnimator anim = ValueAnimator.ofInt(test.getMeasuredHeight(), 800);
anim.setInterpolator(new FastOutSlowInInterpolator());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams params = test.getLayoutParams();
params.height = (int) animation.getAnimatedValue();
test.setLayoutParams(params);
}
});
anim.setDuration(250).start();
This works perfectly, but it expands the view to both sides:
Does anyone know a way to create such animation? Any help is appreciated.
A solution is to keep your implementation but limit the expansion to bottom by having an element above that won't let your view grow up:
Example:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
...
android:layout_height="100dp"/> //assuming your view starts 100dps from top
<YourView
...
.../>
</LinearLayout>
Since your container is a LinearLayout and the first View(FrameLayout) is 100dp height and above the view you wish to expand, it won't expand it's Height up because it can't overlap an element of the same hierarchy, so it will expand down
It also works if you use RelativeLayout by adding android:below="#id/framelayout_id" to YourView which will also guarantee that YourView doesn't expand up
Add an extra variable that holds initial position on Y axis.
expands top
public void expandTop(final View test) {
final float bottomAnchor = test.getY() + test.getHeight();
final ValueAnimator anim = ValueAnimator.ofInt(test.getMeasuredHeight(), 800);
anim.setInterpolator(new FastOutSlowInInterpolator());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams params = test.getLayoutParams();
params.height = (int) animation.getAnimatedValue();
test.setY(bottomAnchor - (int) animation.getAnimatedValue());
test.setLayoutParams(params);
}
});
anim.setDuration(2500).start();
}
expandBottom
public void expandBottom(final View test) {
final float topAnchor = test.getY();
final ValueAnimator anim = ValueAnimator.ofInt(test.getMeasuredHeight(), 800);
anim.setInterpolator(new FastOutSlowInInterpolator());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams params = test.getLayoutParams();
params.height = (int) animation.getAnimatedValue();
test.setY(topAnchor);
test.setLayoutParams(params);
}
});
anim.setDuration(2500).start();
}

Animate margin change

I use this code for animate view in android its work perfect
problem when I set margin to zero or margin less the current margin its doesn't animate
the code
int margin = 100;
ValueAnimator varl = ValueAnimator.ofInt(margin);
varl.setDuration(200);
varl.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) myView.getLayoutParams();
lp.setMargins((Integer) animation.getAnimatedValue(), 0, 0, 0);
myView.setLayoutParams(lp);
}
});
varl.start();
Now when I set margin to 100 it animates, but when I want to set it to zero its set margin without animation
int margin = 0;
ValueAnimator varl = ValueAnimator.ofInt(margin);
varl.setDuration(200);
varl.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) myView.getLayoutParams();
lp.setMargins((Integer) animation.getAnimatedValue(), 0, 0, 0);
myView.setLayoutParams(lp);
}
});
varl.start();
The problem is that you didn't use the ValueAnimator.ofInt(int... values); correctly: you should explicitly tell the animator from which to which value it should animate. So, for example, you should animate from the current value to the wanted value. If your previous value, was, for example, 50, then the statement should be like this:
ValueAnimator varl = ValueAnimator.ofInt(50, margin);
You can use my library for that:
ViewPropertyObjectAnimator.animate(myView).leftMargin(100).setDuration(200).start();

Animating margin change in Android flickers

In my Android app I want to hide/show a Toolbar in an animation and adjust the FrameLayout below it so that it always fills up the whole screen. I do that by animating the top margin of the FrameLayout according to the display status of the Toolbar:
public void toggleToolbars(final boolean show) {
mToolbarHidden = !show;
final Toolbar tt = getBaseActivity().getToolbar();
final FrameLayout cv = getBaseActivity().getContentView();
int translation = show ? 0 : -tt.getHeight();
ValueAnimator animator = ValueAnimator.ofFloat(ViewHelper.getTranslationY(tt), translation).setDuration(200);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float translationY = (float) animation.getAnimatedValue();
ViewHelper.setTranslationY(tt, translationY);
FrameLayout.LayoutParams clp = (FrameLayout.LayoutParams) cv.getLayoutParams();
clp.topMargin = tt.getHeight() + (int) translationY;
cv.setLayoutParams(clp);
}
});
animator.start();
}
This works fine, except for a flickering in the animation. I assume that using setLayoutParams is a costly method. requestLayout() is equally slow. How can I make this animation smoother? Can I reduce the frame rate somehow?
Note, that for certain reasons I cannot use setTranslationY and the built-in animations of CoordinatorLayout.

How to change a View's height in ListView and don't make its child re-layout?

I need to implement this things, a height of item in ListView will be reduced slowly, when its height reduce to 0, it's gone. On this process, the remain views that below the item, should move up slowly.
At First, I use the ObjectAnimator to change the 'scaleY', but the size of item occupy was not changed, when Animator ends, ListView refresh, the empty rectangle was gone.
ObjectAnimator oa = ObjectAnimator.ofFloat(itemView, 'scaleY', 1f, 0f);
And I found another way to do this, I write a Runnable to change the height of the item, but there are some child view in my item, like a ImageView, with the height changing, the ImageView changing too, I think this is not look well.
LayoutParams lp = itemView.getLayoutParams();
lp.height = newHeight;
itemView.setLayoutParams(lp);
At last, I found third way to do, change the 'bottom' value of the item, yes, It looks like a window with reducing height, but height not changed, the remain views that below the item didn't move until Runnable ends and ListView refresh.
itemView.setBottom(itemView.getTop() + newHeight);
How to solve this?
I do something similar to this and work fine:
public void collapse(final View v, final int toHeight, final int toWidth) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = (int) (toHeight * interpolatedTime);
v.getLayoutParams().width = (int) (toWidth * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
a.setDuration(ANIMATION_DURATION);
a.setInterpolator(new AccelerateInterpolator());
v.startAnimation(a);
}
the height set in the layout can not be fixed (put wrap_content). Hope it help you!!

Any way to do an animated crop on an ImageView?

Is there any way to animate a cropping of an ImageView?
Say for example, the ImageView is 720 x 480. I want to chop off the bottom rows of pixels with an animation until the ImageView is completely gone. I have only been able to move the image up when the onclicklistener is enabled, and make it transparent, which is ok, but not what the designer asked for.
ValueAnimator anim = ValueAnimator.ofInt(myImageView.getMeasuredHeight(), 0);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = myImageView.getLayoutParams();
layoutParams.height = val;
myImageView.setLayoutParams(layoutParams);
}
});
anim.setDuration(1000);
anim.start();
I got code from here and just changed it to height: ObjectAnimator animate LinearLayout width
Assuming you only want to chop off the height, using ObjectAnimator will work out to create such a custom cropped-height animation,
First of all you need to specify getHeight() and setHeight() methods and then create a custom animation with ObjectAnimator.
public float getHeight() { ... }
public void setHeight(float h) { ... }
ObjectAnimator heightAnim= ObjectAnimator.ofFloat(yourImageView, "height", heightBegin, heightEnd);

Categories

Resources