Animate subview after animate rootview - android

To summarize and simplify my problem I try to animate a root view and then animate subview.
The first animation work well, but the second most of the time, stay in place.
The layout :
<FrameLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
The sample code :
TranslateAnimation translateAnimation=new TranslateAnimation(0, 0, 0, 300);
translateAnimation.setDuration(2000);
translateAnimation.setFillAfter(true);
translateAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation) {
RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(750);
rotateAnimation.setRepeatCount(Animation.INFINITE);
rotateAnimation.setRepeatMode(Animation.RESTART);
imageView.startAnimation(rotateAnimation);
}
#Override
public void onAnimationRepeat(Animation animation) { }
});
container.startAnimation(translateAnimation);
Sometimes I see the imageview tilted. Or rotate, but just one part.
Someone have an idea of what happen ?
I also tried with setFilterAfter(false) and move my container with setTranslationY() on onAnimationEnd but some frames are visible.
Thanks.
EDIT
In the real case, the TranslateAnimation is on a ViewPager (to QuickReturn pattern) and the RotateAnimation (to PullToRefresh pattern) inside fragment of ViewPager.
So animations is not necessarily sequential like I have done above, and strongly separated (ViewPager/Fragment).
EDIT2
I just see that the touch area don't move with the view.

I'm not saying it's going to work but let's give this a try:
Let's separate animations and not chain them with animationListener; so instead, let's use the ObjectAnimator and AnimationSet to help us sequence animations for us.
ObjectAnimator translateContainer = ObjectAnimator.ofFloat(container, "translationY", 300);
translateContainer.setDuration(2000);
ObjectAnimator rotateImage = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
rotateImage.setDuration(750);
AnimatorSet animSet = new AnimatorSet();
animSet.playSequentially(translateContainer, rotateImage);
animSet.start();

Related

How to animate current Activity (not transition)?

I wonder how to animate current Activity, not transition between activities. For example, I want to shift the activity slightly to the left and then move it back, so that it looks like a little shake effect. Any ideas? Thanks
Finally I have found a solution:
Animation animation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, -0.05f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
animation.setDuration(100);
animation.setInterpolator(new AccelerateInterpolator());
animation.setRepeatCount(1);
animation.setRepeatMode(Animation.REVERSE);
View viewActivity = findViewById(android.R.id.content);
if (viewActivity != null)
viewActivity.startAnimation(animation);
you need to create animation instance like below
Animation startAnimation = AnimationUtils.loadAnimation(context, R.anim.shaking_animation);
then u need to start that animation with your parent layout
parent_layout.startAnimation(startAnimation);
you can get shake animation here shaking / wobble view animation in android
finally you can clear animation like below
parent_layout.clearAnimation();
The basic idea is to get access to the root layout of the activity and then do some animations on it, e.g. if you use DataBindung it is just like this (but not the best idea for the kind of animation you want):
binding.getRoot().animate().rotation(-5).setDuration(500).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
binding.getRoot().animate().rotation(5).setDuration(1000).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
binding.getRoot().animate().rotation(0).setDuration(500);
}
});
}
});

Enlarge ImageView within ListView with animation onClick

I am trying to implement an enlarge animation like it is in WhatsApp. I have a ListView where I have an ImageView at the left of each ListView item. A click on the ImageView should enlarge the image and show it in the middle (almost full screen width).
I tried the Android developer guide suggestion but it did not work for me. So I googled a little bit but could not find "the perfect answer". Here is what I got so far.
private void enlargeProfilePicture(View view, Drawable drawable, View convertView) {
fullScreenImageView.setImageDrawable(drawable);
Animation scale = new ScaleAnimation(
0f, 1f, 0f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scale.setDuration(1000);
final Rect startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();
convertView.getGlobalVisibleRect(startBounds);
rootView.getGlobalVisibleRect(finalBounds, globalOffset);
finalBounds.offset(-globalOffset.x, -globalOffset.y);
Animation translate
= new TranslateAnimation(startBounds.left,
finalBounds.left,
startBounds.top,
finalBounds.top);
translate.setInterpolator(new AnticipateInterpolator());
translate.setDuration(1000);
// Animation set to join both scaling and moving
AnimationSet animSet = new AnimationSet(true);
animSet.setFillEnabled(true);
animSet.addAnimation(scale);
animSet.addAnimation(translate);
// Launching animation set
animSet.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
fullScreenImageView.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
fullScreenImageView.startAnimation(animSet);
}
So root is the container in which my ListView is defined, fullScreenImageView is the ImageView which is showing the Drawable in its enlarged way, convertView is the view inside the ListView (the ListView item itself) and view is the ImageView clicked on.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/root">
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/full_size_profile_picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"/>
</RelativeLayout>
So basically what is going wrong is the translation. How can I find the right starting and ending coordinates for the translation? The scaling animation is working fine.
I'd use Animator rather than Animation.
Animator scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, 2f);
Animator scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, 2f);
AnimatorSet animSet = new AnimatorSet();
animSet.setDuration(300).setInterpolator(new AccelerateDecelerateInterpolator());
animSet.playTogether(scaleX, scaleY);
animSet.start();
Animator is better than Animation, because it modifies the view's properties. Animation just modifies the appearance, but not the view itself.
Use that code if your app's minSdk is higher or equal to 14.
If your app requires at least sdk 11 use this one:
Animator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 2f);
Animator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 2f);
Alright, I fixed the issue. The problem was with how I used the animation constructors. I do not know where I got the code from but I just used it from somewhere else it obviously was working but not for my case. Here is one working example.
private void enlargeProfilePicture(View view, Drawable drawable) {
// view is the ImageView holding the image inside one ListView item
fullScreenImageView.setImageDrawable(drawable);
Animation scale = new ScaleAnimation(0f, 1f, 0f, 1f);
scale.setDuration(1000);
scale.setInterpolator(new LinearInterpolator());
final Rect startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();
view.getGlobalVisibleRect(startBounds);
rootView.getGlobalVisibleRect(finalBounds, globalOffset);
finalBounds.offset(-globalOffset.x, -globalOffset.y);
Animation translate
= new TranslateAnimation(Animation.ABSOLUTE, startBounds.left + view.getWidth()/2,
Animation.ABSOLUTE, finalBounds.left,
Animation.ABSOLUTE, startBounds.top - view.getHeight()/2,
Animation.ABSOLUTE, finalBounds.top);
translate.setInterpolator(new LinearInterpolator());
translate.setDuration(1000);
// Animation set to join both scaling and moving
AnimationSet animSet = new AnimationSet(true);
animSet.setFillEnabled(true);
animSet.addAnimation(scale);
animSet.addAnimation(translate);
// Launching animation set
animSet.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
fullScreenImageView.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
fullScreenImageView.startAnimation(animSet);
}

Fade layout as it slides in slide-out menu

I have a custom slide-out menu implementation (not using any library) in which I slide my layout towards right and show menus on the left (like facebook, google+ app does). After the menu is shown I fade the right layout by giving some alpha value as shown in the code below:
<FrameLayout
android:id="#+id/fl_mask"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:alpha="0.7"
android:background="#color/black">
</FrameLayout>
But this all happens when my menu is shown. What I want is, as the layout slides towards right, I want to darken it. Farther the layout from left edge, darker the layout. Moreover, I use following code for layout animation which slides my layout towards right.
public Animation SlidingAnimation(int animateDuration, boolean slideLeftToright, final boolean executeOnAnimEndCode) {
Animation animation = null;
AnimationSet set = new AnimationSet(true);
if (slideLeftToright) {
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
} else {
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
}
animation.setDuration(animateDuration);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (executeOnAnimEndCode) {
... // Some piece of code
}
}
});
set.addAnimation(animation);
return animation;
}
How can I fade/darken my layout as it slides towards right?
In your
public void onAnimationEnd(Animation animation)
{
if (executeOnAnimEndCode)
{
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.5f);
alphaAnimation.setFillAfter(true);
someLayout.startAnimation(alphaAnimation);
}
}
});
or you can also declare animation as xml and then use it....

android textview animation not smooth

I am trying to perform 2 text animations in a row with my TextView under Android
first:
TextView target = (TextView)findViewById(R.id.textanimation);
target.setText(text1);
target.startAnimation(animationSet1);
animationSet1 is a set of alpha and translate animations:
Animation alpha = new AlphaAnimation(0.0f, 1.0f);
Animation a = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, -1.0f,
Animation.RELATIVE_TO_SELF, 0);
alpha.setDuration( 1000 );
a.setDuration( 1000 );
When onAnimationEnd happens in animationSet1 I immediately start another animation
TextView target = (TextView)findViewById(R.id.textanimation);
target.setText(text2);
target.startAnimation(animationSet1);
However in the 2nd animation I can see on a split of second a fully opaque text, however it should start with 0 alpha. How to avoid this situation? Will appresiate any answer.
P.S. Even if I have 2 separate textviews with the prepared text in both - same bug is seen.
If I put some delay between the animations both of them become smooth.
Sergey
I'm not sure how you are triggering the start of the 2nd animation following the termination of the 1st animation. I'm guessing you're checking to see if the animation on a view is null. This isn't the best or correct way to do it. Instead you should you an AnimationListener
Animation animation1 = new Animation();//Replace with your animation
animation1.setDuration(DURATION_1);
animation1.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation arg0) {}
public void onAnimationRepeat(Animation arg0) {}
public void onAnimationEnd(Animation arg0) {
Animation animation2 = new Animation();
animation2.setDuration(DURATION_2);
view2.startAnimation(animation2);
}
});
view1.startAnimation(animation1);

How can I apply the changes to the position of a view after an animation?

I applyed a TranslateAnimation to an EditText with the FillAfter=true in order to keep its position at the end of the animation.
The animation works properly but the problem is that I can't enter to the edittext anymore.
I think it's due to the fact that the animation affects only the rendering without modifying the actual view coordinates.
Is there any possibility to maintain the final coordinates with the edittext normally working?
Thanks,
Daniele
Unfotunately the animation only renders the raw pixels of the animated element, but not its "android-intern" position. The best solution (that i am able to come up with) is to use an AnimationListener and set the position of the animated element correctly after the animation has finished. Here is my code to slideDown a searchWrapper:
public void toggleSearchWrapper() {
AnimationSet set = new AnimationSet(true);
// slideDown Animation
Animation animation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f
);
animation.setDuration(300);
animation.setFillEnabled(false);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(final Animation anim) {
};
#Override
public void onAnimationRepeat(final Animation anim) {
};
#Override
public void onAnimationEnd(final Animation anim) {
// clear animation to prevent flicker
searchWrapper.clearAnimation();
// set new "real" position of wrapper
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.BELOW, R.id.branchFinderIncludeHeader);
searchWrapper.setLayoutParams(lp);
}
});
set.addAnimation(animation);
// set and start animation
searchWrapper.startAnimation(animation);
}

Categories

Resources