Set view size after ObjectAnimator - android

I have an ImageView which I scale it using ObjectAnimator. Its original size is 220px, and I scale it to 33px, but the problem is that when the animation finishes, the image looks like it is 33px, but if I get its size, it returns me 220px, and if I try to scale it to 33px after the animation is finished it just disappears.
If I change its size to 220px after the animation is finished it doesn't change, like if the ImageView would still be 220px but the image inside and the view's background would be 33px and because of that, when I scale it to 33px, the image and background are even smaller and can't be seen.
What can I do to set the views size to real 33px after animation finishes? :p
Thanks.

Related

Determine final size of ImageView shared element after animation

I have a number of shared elements that I'm transitioning between two activities via ActivityOptions.makeSceneTransitionAnimation. When I enter the second activity, I would like to determine what the final target size that the ImageView will be so I can set the appropriate width of the ImageView. I believe that doing so will allow the object to the right of it (also a shared element) to transition smoothly.
The ImageView is a fitStart scaleType with a fixed height and a wrap_content width. The image will be dynamically loaded and is being shrunk down from the first activity to the second, so I don't know the final width. Before the transition starts, I want to set the ImageView's LayoutParams width to match the final width that it will be after the transition ends.
Currently, the wrap_content property of this ImageView is causing the element to the right of it to not know where its final resting place will be, so it goes off the screen to the right before coming back in and landing in the right place.
Here's a gif of the animation. FIRST ELEMENT is the ImageView, animating correctly, and Second Element is the button to the right of the ImageView:
Notice that when the second activity goes back to the first activity, the Second Element transitions smoothly back to the left of the screen because the end position is known.
When I give the ImageView a specific width like 100dp instead of wrap_content (and then change it back to wrap_content after the transition finishes), Second Element moves more smoothly to its final resting place, but since the ImageView will be dynamically loaded and scaled, I won't know the true width of the image in XML beforehand so there would always be a jerky movement of the Second Element when I change it to wrap_content after the transition.
So I would like to determine the target width of the ImageView and set it programmatically before the transitions begin in the second activity so that Second Element knows how far to the left it needs to go. I've tried playing with ViewTreeObserver and TransitionValues but am missing how to get the final width the ImageView is transitioning to.
Is there something I can call in onCreate of the second activity to determine what width the ImageView will end up at after the transition?
EDIT
I tried the solution in this answer but it's reporting back the ImageView's beginning width, not the final width it's transitioning to. For reference, these are the layouts of the two activities I'm switching between:
Note that I'm moving AND shrinking the ImageView.
I tweaked the answer's code since I'm not using the support library and had to move to imageView.getViewTreeObserver() in the onPreDraw() call to avoid an IllegalStateException:
postponeEnterTransition();
final ImageView imageView = (ImageView) findViewById(R.id.image_view);
final ViewGroup.LayoutParams imageViewLayoutParams = imageView.getLayoutParams();
final ViewTreeObserver viewTreeObserver = imageView.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override public boolean onPreDraw() {
imageView.getViewTreeObserver().removeOnPreDrawListener(this);
// You can acquire the width here
logoLayoutParams.width = imageView.getWidth();
Log.i(TAG, "width is " + imageViewLayoutParams.width);
imageView.setLayoutParams(imageViewLayoutParams);
// `imageView` has been laid out, but not yet been drawn
startPostponedEnterTransition();
return true;
}
});
The log is reporting a width of 998, which is the larger size of the imageView in Activity 1 (its starting size before the transition). So the Second Element is still flying off the screen.
Now that I have this code in place, I can use the aspect ratio information of the larger image to figure out the final width that the smaller image will be since I know the final height, but is that guaranteed with the fitStart scaleType?
It would be really nice to know if Android can tell me the final size the shared element targeting.
Here's the case: if you change in the second activity the resource from #drawable/first_element to #drawable/first_element_thumb, you'll no long experience that behavior. The downside is, that you'll see a glitch each time the transition is starting, that's because the drawable is being changed from high resolution to a low resolution right before transition starts.
Here's with 300ms animation time:
Here's with 5000ms animation time:
If you want the transitioning to be without that glitch, than the solution is to start the transition from high resolution drawable and substitute that drawable to a low resolution whilst transitioning the view. You can see Nick Butcher describing the feature in his "Animatable" talk. You'll end up writing your custom transition class like this one.

Android Animation in ImageView is stretched vertically

Everything looks perfect when I use the ImageView to show a png image like this:
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/png_picture"
android:src="#drawable/paos_connection"/>
The image is scaled perfectly, fills the screen horizontally and has the correct aspect ratio.
Now, I want to replace the image with an animation. I decided on using Frame Animation as shown here: http://developer.android.com/guide/topics/graphics/view-animation.html. I am using the same size png files (slightly modified copies of the original one).
My problem is that the animation is playing and it is filling up the screen horizontally as before, but it is now stretched vertically. I can force it to have the correct height by hard-coding a height:
<ImageView
android:layout_width="fill_parent"
android:layout_height="210px"
android:id="#+id/animation" />
...but obviously this is not a good solution because the image should have the correct aspect ratio on all screen sizes.
This may help. I've found without a lot of footwork, you're stuck using a fixed element unless the image is drawn in order with the rest of the layout on initialization.
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
A quick hack to try would be to set a transparent image in its place with the same dimensions as the animated image. Programatically create an ImageView using the width & height of the rendered transparent image. Following that, animate the the instantiated image.
Instead of setting the animation drawable in the background of the imageview, set it in the foreground using src and let the animation play there. All images in the frame animation will be resized with aspect ratio intact provided you set a suitable scale type for the imageview.
Althought the question is 11 years old, for those who search:
ImageView img_anim;
img_anim = view.findViewById(R.id.img_anim);
img_anim.setImageResource(R.drawable.anim_youranimation);
AnimationDrawable frameAnimation = (AnimationDrawable) img_anim.getDrawable();
frameAnimation.start();
instead of
ImageView img_anim;
img_anim = view.findViewById(R.id.img_anim);
img_anim.setBackgroundResource(R.drawable.anim_youranimation);
AnimationDrawable frameAnimation = (AnimationDrawable) img_anim.getBackground();
frameAnimation.start();

Android Imageview with AnimationDrawable source changes size

I have made a set of 3 images that will represent the move of a animal. Each image represents a frame and consists only in the animal with transparent background.
I have made a AnimationDrawable in code and created the animation:
AnimationDrawable staticAnimation = new AnimationDrawable();
staticAnimation.addFrame(ctx.getResources().getDrawable("frame1"),150);
staticAnimation.addFrame(ctx.getResources().getDrawable("frame2"),150);
staticAnimation.addFrame(ctx.getResources().getDrawable("frame3"),150);
I set the animation as a background for a Imageview and start it
imgAnimal.setBackgroundDrawable(staticAnimation );
staticAnimation.start()
Because the frames have different width (the drawing needs to recreate steps move) looks like the Imageview resizes the images in the animation. Better to say, if frame1 is bigger then frame2, frame 1 is displayed ok but frame 2 is stretched to be as big as frame1 was. Looks really awful.
Any suggestions on how to stop this behavior ? Thank you.
The solution was quite simple, because images in frames have same height but different width, I simply made a transparent border rectangle and put it over each frame. In this case each frame will have the same width and the animatin will run as supposed to.

How to position a view off-screen so that it can be Animated to move on-screen?

I have a RelativeLayout filling the screen and a couple of ImageView positioned on it using LayoutParams margins. These ImageView are animated in different ways, and in one case I want an image to "fly in" to the screen from the right.
Unfortunately, if I set leftMargin for that ImageView greater than the width of the screen, it does not appear (or appears cropped if it partially visible at the start of animation).
I tried setting width and height of RelativeLayout to be bigger than screen size - it works, but only partially: if the image is positioned completely off-screen, it does not work, and if the image is partially visible, it is not cropped, but that works only for right and bottom sides.
So, my question is this: how to position several ImageViews on and off the screen so that I can animate them using Animation?
In the end, I used a trick: I combined AnimationDrawable and view animation. I did the following (assuming that the animation has to run T milliseconds):
Position that ImageView on-screen.
Set as its background an AnimationDrawable with following frames:
empty Drawable: 1ms,
normal Drawable: Tms.
Change view's animation to this:
jump to off-screen position (translation with duration=1ms),
do normal animation.
This is probably a good place to start looking for those who would use Fixpoint's solution.
Android — How to position View off-screen?

Resize layout after an image transformation android

I have a layout in which I resize an image by doing a transformation with prescale. After the scale the image has the right size, but the layout container around it cuts its size of. I want the layout container arround it to show to complete image.
I just tried invalidate on the image, the container as well as requestLayout(). Any ideas?
Thanks
How are you transforming the image? If you are setting a matrix on an ImageView, you need to tell the ImageView to adjust its bounds to the size of the content. If you are scaling the image by setting a transformation on the Canvas, you must change the dimensions of the View yourself.

Categories

Resources