I have a main activity which keeps 2 fragments.
On the first fragment i call an animation from the main activity.
If i call it from a button it animates and everything is ok
If i try to call it automatically (like if(x>3) animate()) it doesn't show the animation at all and in addition if i push the button it continues not to showing the animation. the code is below
Parent
public void showAnimation()
{
AnimationSet as = new AnimationSet(true);
Animation up = AnimationUtils.loadAnimation(this.getBaseContext(), R.anim.slide_up);
up.setStartOffset(2000);
Animation down = AnimationUtils.loadAnimation(this.getBaseContext(), R.anim.slide_down);
down.setStartOffset(6000);
as.addAnimation(up);
as.addAnimation(down);
Log.v("FFF","ok");
test.setVisibility(View.VISIBLE);
test.startAnimation(as);
test.setVisibility(View.GONE);
}
Child
if(!settings.getBoolean(BADGE_D7, false)){
if (days >= 7){
days7.setImageResource(R.drawable.days7);
Log.v("FFF","done");
parent.showAnimation();
}
}
and in the constructor of the child i have
public Child(MainActivity p) {
this.parent = p;
}
by the way the log messages are shown up the only problem is the animation. What is the problem??
Well, i kinda found out a solution, it's not the best but it works.
First i put all the code in the child activity and i use it from there. I access the textView from the child and i added a treeObserver
test = (TextView) parent.findViewById(R.id.test1);
ViewTreeObserver vto = test.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
ready = true;
return true;
}
});
and I edited the showAnimation() like this:
public void showAnimation()
{
as = new AnimationSet(true);
Animation up = AnimationUtils.loadAnimation(this.getActivity(), R.anim.slide_up);
Animation down = AnimationUtils.loadAnimation(this.getActivity(), R.anim.slide_down);
down.setStartOffset(4000);
as.addAnimation(up);
as.addAnimation(down);
Log.v("FFF","ok");
while(!ready){} //Added this line
test.setVisibility(View.VISIBLE);
test.startAnimation(as);
test.setVisibility(View.GONE);
}
so while the TextView isn't in place it is stucks in a loop until everything is ok.
I had a view that I declared at the end of my layout to keep its Z index above its siblings. I had to touch the page to make the animation work.
So I set the Z index again through Java and it worked.
view.bringToFront();
Related
I have created a rotate animation when the answer is false it shake the CardView,
But it doesn't work until i change the view state such as < cardView.setVisibility(View.INVISIBLE) >
or calling nextQuestion().
AND Please suggest which class to choose for animation ObjectAnimator, Animation etc..
public void checkAnswer(boolean isTrue) {
if (isTrue == questionList.get(questionCount).getAnswer()) {
Toast.makeText(this, R.string.correct_answer, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, R.string.wrong_answer, Toast.LENGTH_SHORT).show();
shakeAnimation();
}
}
public void nextQuestion() {
if (questionCount < questionList.size()) {
question_textView.setText(questionList.get(++questionCount).getQuestion());
question_counter.setText((questionCount + 1) + "/" + questionList.size());
}
}
public void shakeAnimation() {
Animation shake = AnimationUtils.loadAnimation(MainActivity.this, R.anim.shake_animation);
cardView.setAnimation(shake);
}
You are only setting the animation.so whenever the view will be drawn or recreated your animation will work.
You have to call the start animation method on the view to show animation.
For Example in your case code will be
public void shakeAnimation() {
Animation shake = AnimationUtils.loadAnimation(MainActivity.this, R.anim.shake_animation);
cardView.startAnimation(shake);
}
Difference between setAnimation and startAnimation method
- SetAnimation
when the view is added to the view group, the animation will be called. when the view has been added, the animation will not be called
- StartAnimation
the animation will be called all the time even though the view has been added.
Note: StartAnimation internally call setAnimation method.
I want to use animate on videoView which is above the imageView and recyclerView. At first, videoView's visibility is Gone and when i click on the item on the recyclerView i want to make videoView Visible with the animation sliding down and also use animation to the imageView to slideUp and make it Gone. How can i do that. I have given the snapshot of before and after of the layout.
Before Animation:
After Animation:
This is what I have done for a similar situation. In your layout you need to put both views one above the other (on the exact places where they have to appear). Add the global layout listener to the videoView / imageView once in onCreate and then just change the visibility of the according view. This code could be reused with the imageView, but keep in mind that you cannot change the visibility of both views at the same time, because they will overlap. Maybe you need to wait for the first animation to go off and then show the next. It's up to you.
private static final int ANIMATION_DURATION = 350;
private void addVideoViewAnimation(final View videoView) {
videoView.setTag(videoView.getVisibility());
videoView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int newVisibility = videoView.getVisibility();
if ((int) videoView.getTag() != newVisibility) {
videoView.setTag(newVisibility);
TranslateAnimation animation;
if (newVisibility == View.VISIBLE) {
animation = new TranslateAnimation(0, 0, -videoView.getHeight(), 0);
animation.setInterpolator(new DecelerateInterpolator());
} else {
animation = new TranslateAnimation(0, 0, 0, -videoView.getHeight());
animation.setInterpolator(new AccelerateInterpolator());
}
animation.setDuration(ANIMATION_DURATION);
videoView.startAnimation(animation);
}
}
});
}
I have a LinearLayout with RelativeLayout children. Each RelativeLayout has a background image like a file cabinet. I am trying to animate the drawers dropping down into view one after another with a smooth delay. Everything I have tried plays all animations at once. I have this as my method for animating each drawer:
private void dropAndPause(final RelativeLayout drawer){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_down);
animation.setStartOffset(750L);
drawer.startAnimation(animation);
}
}, 1200);
}
I have also tried this:
View[] views = new View[] { ... };
// 100ms delay between Animations
long delayBetweenAnimations = 100l;
for(int i = 0; i < views.length; i++) {
final View view = views[i];
// We calculate the delay for this Animation, each animation starts 100ms
// after the previous one
int delay = i * delayBetweenAnimations;
view.postDelayed(new Runnable() {
#Override
public void run() {
Animation animation = AnimationUtils.loadAnimation(context, R.anim.your_animation);
view.startAnimation(animation);
}
}, delay);
}
Instead of View[] views, I used this:
View[] drawers = new View[] {
drawerOne, drawerTwo, drawerThree, drawerFour, drawerFive
};
Which plays, again, all of the animations at once. How can I get each "drawer"/view to slide in one at a time? Also, should I have each view as visibility GONE initially?
If you want to animate the views inside a layout, then it's much easier to use layout animations. Basically, you need to load an animation, create a LayoutAnimationController, set the delay on it, and launch the animation. Here's some sample code.
Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_down);
animation.setStartOffset(750L);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(0.1F);
viewGroup.setLayoutAnimation(controller);
viewGroup.startLayoutAnimation();
The delay here is set as fraction of the animation duration.
So in my android app I have a HorizontalScrollView that will display images. All images are downloaded an added to the View before it is avalible to the user. However when it does apear I want each image to animate in seperatly. Ive tried a LayoutTransition object attached to my layout with this code to show the views:
transition = new LayoutTransition();
transition.setStagger(LayoutTransition.APPEARING, 500);
transition.setDuration(1000);
transition.setAnimateParentHierarchy(true);
for (int i = 0; i < mGallery.getChildCount(); i++) {
mGallery.getChildAt(i).setVisibility(View.VISIBLE);
transition.showChild(mGallery, mGallery.getChildAt(i));
}
I have also tried this method using the the AnimationEndListener, and a recursive animateView() method
private void animateView(final int index) {
if (mGallery.getChildAt(index) == null)
return;
final View child = mGallery.getChildAt(index);
final Animation an = AnimationUtils.loadAnimation(mRootView.getContext(), R.anim.slideup);
AnimationEndListener listener = new AnimationEndListener() {
#Override
public void onAnimationEnd(Animation animation) {
animateView(index + 1);
}
};
an.setAnimationListener(listener);
child.setAnimation(an);
child.setVisibility(View.VISIBLE);
an.start();
}
The first method is preferable however it always animates in all my images at the same time. The second method kind of works, however it will apply the animation to the first view and the all subsequent views will appear in sequence without the animation playing.
I want to build an animation of TextViews, which repeats itself just after completion.
For each View I want to animate, I use the following piece of code
final float oldX = v.getX();
final float newX = v.getX() - (float)totalWidth;
final AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
v.setX(oldX);
animFinished = true;
//This line won't compile
//v.animate().setDuration(animDuration).setInterpolator(newsInterpolator)
// .setListener(listener).x(newX);
}
};
v.animate().setDuration(animDuration).setInterpolator(newsInterpolator)
.setListener(listener).x(newX);
I tried to place the last piece of code into the onAnimationEnd, but Java will not compile since it considers the object listener as not initialized. Moreover, I don't think that this "recursive" animation invocation is a good solution, it was the first thing which came to my mind. I am suspicious that there is a simple and sound way to implement looping property animation, but I failed to locate it, so I turned here for help.
Thanks in advance
Well, I am going to answer myself again.
TranslateAnimation class has methods about repeating the animation, so I used it instead of ViewPropertyAnimator.
The following code seems to work:
long duration = 1000* ((long)totalWidth / newsScrollSpeed);
System.out.println("totalWidth="+totalWidth);
TranslateAnimation anim = new TranslateAnimation(0,-totalWidth,0,0);
anim.setInterpolator(linearInterpolator);
anim.setDuration(duration);
anim.setRepeatCount(TranslateAnimation.INFINITE);
anim.setRepeatMode(TranslateAnimation.RESTART);
for(i=0;i<this.getChildCount();i++)
{
View v = this.getChildAt(i);
if(v.getId() == R.id.yuruyen_yazi)
{
continue;
}
v.startAnimation(anim);
}
Not elegant way, but it works:
Runnable runnable = new Runnable() {
#Override
public void run() {
// update newX
v.animate().setDuration(animDuration).setInterpolator(newsInterpolator).x(newX).withEndAction(this).start();
}
};
v.animate().setDuration(animDuration).setInterpolator(newsInterpolator).x(newX).withEndAction(runnable).start();