In a RelativeLayout, I added an ImageView with some margin set in LayoutParams:
RelativeLayout.LayoutParams rlLayoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rlLayoutParams.topMargin = (int) convertDpToPixel(kMARGIN_HEADER);
rlLayoutParams.leftMargin = (int) myMAGIC_MARGIN;
Now this ImageView is somewhere in the middle of the screen. I want to have it slide a few hundred pixels to its right, and stay there, so I applied the following TranslateAnimation:
private TranslateAnimation getAnimation(ImageView view, int displacement, int duration) {
int[] view_pos = new int[2];
view.getLocationOnScreen(view_pos);
TranslateAnimation slide = new TranslateAnimation(
view_pos[0],
view_pos[0] + displacement,
view_pos[1],
view_pos[1]);
slide.setFillAfter(true);
slide.setDuration(duration);
return slide;
}
Immediately after applying this animation, the whole view is gone. I checked the value of view_pos[] in debug mode, they are fine (not all zeroes). If I make the setFillAfter to false, then the view will come back after animation duration (for obvious reasons). So where did it go?
I also tried the following:
TranslateAnimation slide = new TranslateAnimation(
view_pos[0],
view_pos[0], // don't do the + displacement,
view_pos[1],
view_pos[1]);
I was expecting the view to stay where it is. But no, it was vanished as well, with a chance of coming back afterwards, depending on the value of setFillAfter.
I start to think I cannot apply TranslateAnimation if the view was placed by LayoutParams in a RelativeLayout. How should I achieve the goal of sliding the view?
The parameters for TranslateAnimation are deltas not positions, so you just want:
slide = new TranslateAnimation(0, displacement, 0, 0).
If you don't need to support Android <3.0 then use a Property Animation instead of a View Animation - see the Android docs for more details.
Related
So my problem is that i want after double click on item in RecyclerView adapter to trigger the animation on ImageView. I detect the double tap in adapter, take the coordinates of the tapped area in format of int[] location, call the method in Fragment passing the location.
public void performAnimation(int[] location) {
ImageView imageView = new ImageView(getContext());
imageView.setImageDrawable(getActivity().getDrawable(R.drawable.ic_imageview));
ConstraintLayout.LayoutParams params =
new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0, location[0], 0, location[1]);
imageView.setLayoutParams(params);
parentViewGroup2.addView(imageView);
ObjectAnimator translateAnim = ObjectAnimator.ofFloat(imageView, View.TRANSLATION_Y, 0.5f);
translateAnim.setDuration(2000);
translateAnim.start();
So the problem is that i only get to draw the image in layout, but animation wont start. I have also tryed that with TransitionManager with beginDelayedTransition, but again, nothing. Does anyone have any idea what am i doing wrong? Thanks in advance.
ObjectAnimator.ofFloat receives an array of float values of which value the animation will run through, you only pass 1 0.5f param which is not enough. Also, the float here should be an absolute pixel on the screen will be translated, not an offset value.
Try this ViewPropertyAnimator instead:
imageView.animate().translationY(400).setDuration(200).start();
What I want to do is simultaneously scale and translate an ImageView based when the user touches is. The final position and size of the ImageView should be equal to the target.
Below is a snipper of the OnClickListener attached to every ImageView that should perform this action. The new position and size is obtained from ivYou, which also is an ImageView.
#Override
public void onClick(View v) {
// Create animations
int[] from = new int[2];
int[] to = new int[2];
//v.getLocationInWindow(from);
v.getLocationOnScreen(from);
//ivYou.getLocationInWindow(to);
ivYou.getLocationOnScreen(to);
TranslateAnimation transAnim = new TranslateAnimation(0, to[0] - from[0], 0, to[1] - from[0]);
float factorX = ivYou.getWidth() / v.getWidth();
float factorY = ivYou.getHeight() / v.getHeight();
ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, factorX, 1.0f, factorY);
// Create animation set
AnimationSet set = new AnimationSet(true);
set.setFillAfter(true);
set.setDuration(ANIM_DURATION);
set.addAnimation(transAnim);
set.addAnimation(scaleAnim);
// Start animations and disable click listener
v.startAnimation(set);
v.setOnClickListener(null);
}
ANIM_DURATION is 2000 miliseconds.
When I run this code the strangest things happen. The ImageView turns half a circle and gets smaller then its supposed to be. When I do not add the ScaleAnimator to the animation set, then the ImageView is moved to the new position. However, this new position isn't the same for every ImageView. Note that the ImageView's with this OnClickListener all have a different initial position.
Any help and feedback is greatly appreciated!
I was able to achieve this animation by wrapping the target View in a layout group and animating them separately.
In other words, I translate the wrapper layout, and scale the child view. Translating and scaling the same view at the same time always seems to result in unexpected animation trajectories as the scaling messes with the coordinate system the translate animation is using.
translateTarget.animate().x(deltaX).y(deltaY).setDuration(1000);
scaleTarget.animate().scaleX(0.01f).scaleY(0.01f).setDuration(1000)
Did you try this constructor?
ScaleAnimation (float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) and have pivotX be widthofimageview/2 and pivotY be the heightofimageview/2 for it to be the center. This is what I used in my translate scale animation.
I have a LinearLayout (called layout) with height as fill_parent and an initial top margin of 200dp inside a RelativeLayout.
When I clicked a button, I want the topMargin to become 0, expanding the LinearLayout.
I am using the next code:
final RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
Animation animation = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
int topMargin = (int)((1-interpolatedTime)*200);
layoutParams.setMargins(0, topMargin, 0, 0);
layout.setLayoutParams(layoutParams);
LogThis.debug("topMargin: "+topMargin);
}
};
animation.setDuration(1000);
layout.startAnimation(animation);
The problem is that although it makes an animation, it is not soft. It does the transformation in 4 steps, so it does not look good.
Do you have any idea how to make this kind of transformation softly?
Thank you in advance.
EDIT
I have this in the first moment:
And after the animation I want this:
With the TranslationAnimation I get this:
the choppy animation is happening because that's not how the Animation are supposed to be used. Those are to be use Transformation object passed onto the method.
But because you're using a simple translation you can easily achieve that using a TranslateAnimation like on this answer:
translate animation
I want to have myView move deltaX, deltaY pixels from current position.
But it moves two times longer than I want.
This is caused by setLayoutParams in onAnimationEnd.
Without that, myView's real positon is not changed.
How can I change myView's real positon and animate normally?
class MyLayout extends RelativeLayout {
Animation animation;
MyView myView;
animation = new TranslateAnimation(0, deltaX, 0, deltaY);
animation.setDuration(100);
animation.setFillAfter(true);
myView.startAnimation(animation);
}
class MyView extends ImageView {
protected void onAnimationEnd() {
super.onAnimationEnd();
LayoutParams params = (LayoutParams)getLayoutParams();
params.leftMargin += deltaX;
params.topMargin += deltaY;
setLayoutParams(params);
}
}
If you want to avoid doing the desired translation of the view twice as you are doing it now, you have to set the "setFillAfter" flag for the animation to false. As the documentation says "When setFillAfter is set to true, the animation transformation is applied after the animation is over."
On the other hand if you leave the "setFillAfter" flag to true, the view should translate to the desired location and no LayoutParams modification is needed in onAnimationEnd method. So it might be that something is blocking the transformation, if you could provide further information about the layout that the view is part of, it would be mostly helpful.
Another thing is that setting the margin of the layout params to move the view is not entirely the best idea. Take it more like a hack. Rather try to set the position of the view directly or try to play with weights in your parent view. That way you will get the same effect on multiple different screens.
I have a LinearLayout (LayoutContentView) which can contain one or two view (SubView1 and SubView2) (they are eitherTextView or ImageView).
This layout is in another LinearLayout (MyScreenLayout).
I want to make an animation on LayoutContentView so it can move and show just a part of it in MyScreenLayout.
Both of these layouts have setClipChildren(false); so it can let it's children draw outside it-self.
Depending on different parameters, I can change the size of the content, and the size of the content I will show.
Basically, I expend from top to bottom to show the two subviews and unexpend for bottom to top to show only the second subview. Before I expend, I increase the size of the LayoutContentView, so it can show the two subviews, and after I unexpend, I decrease the size of the LayoutContentView, so it can only show the second subview, and it let space on the screen for other elements.
Here is my method for expending and un-expending LayoutContentView :
mLayoutContentView.clearAnimation();
float yFrom = 0.0F;
float yTo = 0.0F;
float xFrom = 0.0F;
float xTo = 0.0F;
if (expend) { // if we expend
// I change the height of my LayoutContentView so it we can show it's two subviews
final android.view.ViewGroup.LayoutParams lp = mLayoutContentView.getLayoutParams();
lp.height = subView1H + subView2H;
setLayoutParams(lp);
invalidate();
// we start the animation so it shows only the second subview
yFrom = -subView1H;
// and we animate from top to bottom until it shows the two subviews
yTo = 0;
} else { // if we un-expend
// we animate from bottom to top starting by showing the two subviews
yFrom = 0;
// and progressively hiding the first subview and showing only the second subview
yTo = -subView1H;
}
Animation anim = new TranslateAnimation(xFrom, xTo, yFrom, yTo);
anim.setDuration(1000);
anim.setFillAfter(true);
anim.setFillEnabled(true);
anim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (!expend) {
// if we un expend at the end of the animation we can set the size of LayoutContentView to the size of the second subview again
final android.view.ViewGroup.LayoutParams lp = mLayoutContentView.getLayoutParams();
lp.height = subView2H;
mLayoutContentView.setLayoutParams(lp);
invalidate();
}
}
});
mLayoutContentView.startAnimation(anim);
The way I made my animation I need it to apply on LayoutContentView, the layout which contain two subview, and with startAnimation() it doesn't do the animation.
I tried to use a LayoutAnimationController, but instead of doing the animation on the LayoutContentView, it does it on each of its children...
I also tried to do the animation on each children myself, but I don't know why, the second subview isn't shown.
Each time I've tried to use HierarchyViewer, but it's does see the change made by the animation.
Does anyone know a solution or have faced the same problem and found a good solution ?
EDIT :
Well it seems that if you set a background color to your TextView and move them with animation, the background move but even if you have set the fill after parameter to your animation, the background moves back to it's original position or something like that, and therefore as I set a background color to both of my SubViews, somewhat one of the SubView's background hide the background of the other...
And there also a problem if after the animation, one of the SubView is still outside the its layout, there is also a problem during the animation, so I add a limitation to what I intended to here too.