I have a listview with entries which have a fade out animation when the user deletes\edits an entry in the list.
For some reason, after I perform the action (edit\delete) the animation will not start until I press the screen again. Only they will the animation actually perform.
From this method the animation is being called:
public void replace(View view, long position) {
int hoursSum = 0;
int minuteSum = 0;
boolean hoursIssue = false;
if (finsihIntMinutes >= startIntMinutes) {
minuteSum = finsihIntMinutes - startIntMinutes;
} else if (finsihIntMinutes < startIntMinutes) {
minuteSum = (finsihIntMinutes + Utility.MINUTES_TIME_UNIT)
- startIntMinutes;
hoursIssue = true;
}
if (finishIntHours >= startIntHours) {
hoursSum = finishIntHours - startIntHours;
if (hoursIssue == true) {
--hoursSum;
}
} else if (finishIntHours < startIntHours) {
hoursSum = (finishIntHours + Utility.HOURS_TIME_UNIT)
- startIntHours;
}
double salper = (minuteSum * Main.sal) / 60;
double salper2 = hoursSum * (Main.sal);
String madeSoFar = ""
+ String.valueOf(formatter.format(salper2 + salper));
String edited = "**Edited**";
String totalTime = "" + hoursSum + ":" + minuteSum;
DB.edit(position, Shifts.editDate, Shifts.editStartTime,
Shifts.editEndTime, Shifts.dayString, totalTime, minuteSum,
madeSoFar, edited, totalHours, totalMinutes);
moneySummary = getMoney();
hoursSummary = "Total Hours: " + getHours();
summary.setText(moneySummary);
**FastScrollAdapter.animate(Shifts.view);**
}
Here is the animation code:
public static void animate(final View v) {
Animation out = new AlphaAnimation(1, 0);
out.setInterpolator(new DecelerateInterpolator());
out.setDuration(350);
v.setAnimation(out);
out.start();
out.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.i("Animation", "Started");
}
#Override
public void onAnimationRepeat(Animation animation) {
// Shifts.setSummaryCursor.requery();
Shifts.getMoneyCursor.requery();
FastScrollAdapter.cursor.requery();
Shifts.CA.notifyDataSetChanged();
}
#Override
public void onAnimationEnd(Animation animation) {
// Shifts.setSummaryCursor.requery();
Shifts.getMoneyCursor.requery();
FastScrollAdapter.cursor.requery();
Shifts.CA.notifyDataSetChanged();
Log.i("Animation", "Ended");
}
});
}
I had exactly the same problem, I solved it by calling
view.clearAnimation();
just before
view.startAnimation(animation);
I think you need to change the order
1. v.setAnimation(out);
2. out.setAnimationListener(new AnimationListener());
3. v.startAnimation(out);
I had a similar problem: the animation was not performet in the UE thread. Try to run the animation posting it in the UE thead:
mHandler.post(new Runnable() {
#Override
public void run() {
yourView.startAnimation(yourAnimation));
}
});
Related
i know this is asked before i tried all the solution but i cannot arrive to fix it,
i have objects that fall from the top of the screen to the bottom of the screen using translation in android library.
i want to the pause the animation and resume it:
PAUSE CODE fixed from the suggestion on one of the stack overflow posts:
private void pauseAnimation() {
p = true;
Pausearray = new MyClass[mAllImageViews.size()];
int count = 0;
for (ArrowView v : mAllImageViews) {
ValueAnimator va = (ValueAnimator) v.getTag();
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
va.pause();
} else {
if (va != null) {
MyClass temp = new MyClass();
temp.tag = v.getTag().toString();
temp.playtime = va.getCurrentPlayTime();
Pausearray[count] = temp;
va.cancel();
}
}
count ++;
}
}
the pause is working the annimation is stoping from moving and its staying in its position.
RESUME CODE suggested by one of the stack overflow posts:
private void resumeAnimation() {
p = false;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
for (ArrowView v : mAllImageViews) {
try {
ValueAnimator va = (ValueAnimator) v.getTag();
va.resume();
} catch (Exception ex) {
}
}
} else {
if(Pausearray!=null) {
for (ArrowView v : mAllImageViews) {
ValueAnimator va = (ValueAnimator) v.getTag();
for (int i = 0; i < Pausearray.length; i++) {
if(v.getTag().toString().equalsIgnoreCase(Pausearray[i].tag)){
va.start();
va.setCurrentPlayTime(Pausearray[i].playtime);
}
}
}
}
}
}
the problem with the resume that it's starting from the top again i want it to continue where it was it's position on screen. Thank you!
Update:
i tried to get the arrow view position from screen and set it at resume, i'm still getting the same issue, views are restarting so the edited code is:
private void resumeAnimation() {
p = false;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
for (ArrowView v : mAllImageViews) {
try {
ValueAnimator va = (ValueAnimator) v.getTag();
va.resume();
} catch (Exception ex) {
}
}
} else {
if(Pausearray!=null) {
for (ArrowView v : mAllImageViews) {
ValueAnimator va = (ValueAnimator) v.getTag();
for (int i = 0; i < Pausearray.length; i++) {
if(v.getTag().toString().equalsIgnoreCase(Pausearray[i].tag)){
Log.w("PAUSETEST","Setting Parameters "+Pausearray[i].playtime);
va.start();
va.setCurrentPlayTime(Pausearray[i].playtime);
v.setY(Pausearray[i].translationy); // i took the location via v.gettranslationY on pause
}
}
}
}
}
}
UPDATE:
i heard while i was searching that valueanimator doesn't restart so i switched the valueanimator to object animator animator code:
public void startAnimation(final ArrowView aniView) {
aniView.setPivotX(aniView.getWidth());
aniView.setPivotY(aniView.getHeight());
long delay = new Random().nextInt(Constants.MAX_DELAY);// generate a random delay time before the animation starts to go down
ObjectAnimator animator = ObjectAnimator.ofFloat(aniView,"translationY", mDisplaySize.bottom - (buttonsize) - (90 * mScale));
if (aniView.getColor() == 0 && aniView.draw == false) {
Constants.ANIM_DURATION = Constants.ANIM_DURATION_NORMAL;
} else if (aniView.getColor() != 0 && aniView.draw == false) {
Constants.ANIM_DURATION = Constants.ANIM_DURATION_COLOR;
} else if (aniView.getColor() == 0 && aniView.draw == true) {
Constants.ANIM_DURATION = Constants.ANIM_DURATION_COLOR;
} else if (aniView.getColor() != 0 && aniView.draw == true) {
Constants.ANIM_DURATION = Constants.ANIM_DURATION_COLORANDCALC;
}
animator.setDuration(Constants.ANIM_DURATION);// speed of the falldown
animator.setInterpolator(new AccelerateInterpolator());
animator.setStartDelay(delay);// start the animation after the delay.
// animator.addUpdateListener(new AnimatorUpdateListener() {
//
// //int angle = 50 + (int) (Math.random() * 101);
// //int movex = new Random().nextInt(mDisplaySize.right);
//
// #Override
// public void onAnimationUpdate(ValueAnimator animation) {
// float value = ((Float) (animation.getAnimatedValue())).floatValue();
// //aniView.setRotation(angle*value);
// //aniView.setTranslationX((movex-40)*value);
// aniView.setTranslationY((mDisplaySize.bottom - (buttonsize)) * value - (90 * mScale));// set the translation to fall down and stop on the top of buttons
// }
// });
aniView.setTag(animator);
animator.start();
}
and i changed the code of the pause/resume to cast it into object animator and I'm still facing the same problem... on start is restarting the animation! please someone help! thanks!
After Playing around with valueanimator class i figured out a trick to make the animation stop, and resume its not an authentic way, but it solves the problem, i extended from value animator class and replaced the normal animator in my main class with the myvalueanimator class and here the play around in the value animator class:
import android.animation.ValueAnimator;
import android.util.Log;
import java.util.Timer;
/**
* Created by win7 on 6/21/2017.
*/
public class MyValueAnimator extends ValueAnimator {
private float animatedValue = 0;
private long currenttime;
private long totaltime;
private boolean onetime = true;
private volatile boolean mPaused = false;
private Timer t;
public void pause() {
animatedValue = (float) getAnimatedValue();
mPaused = true;
}
// #Override
// public void setValues(PropertyValuesHolder... values) {
// if (mPaused)
// return;
// super.setValues(values);
#Override
public Object getAnimatedValue() {
if (mPaused) {
if(onetime){
currenttime = getCurrentPlayTime();
// totaltime = getStartDelay()+ (getDuration() * (getRepeatCount() + 1));
totaltime = getDuration();
setDuration(Long.parseLong("9999999999999999"));
Log.w("PauseDur",Long.parseLong("9999999999999999")+"");
onetime =false;
}
return animatedValue;
}
return super.getAnimatedValue();
}
public void resume() {
mPaused = false;
onetime=true;
setCurrentPlayTime(currenttime);
setDuration(totaltime);
}
public MyValueAnimator(float from, float to) {
setFloatValues(from, to);
}
}
I have a TextView showing integer value. Integer value is transferred from previous activity, and I want to add nice animation. I want to if for example int value is 73, I want textView to increase shown number by 1 until 73, so it would be 1-2-3-4-5...etc etc.
How can I do this?
The best solution in my opinion is to use this method :
public void animateTextView(int initialValue, int finalValue, final TextView textview) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(initialValue, finalValue);
valueAnimator.setDuration(1500);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
textview.setText(valueAnimator.getAnimatedValue().toString());
}
});
valueAnimator.start();
}
Here is a simple function to animate the text of a textView according to an initial and final value
public void animateTextView(int initialValue, int finalValue, final TextView textview) {
DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(0.8f);
int start = Math.min(initialValue, finalValue);
int end = Math.max(initialValue, finalValue);
int difference = Math.abs(finalValue - initialValue);
Handler handler = new Handler();
for (int count = start; count <= end; count++) {
int time = Math.round(decelerateInterpolator.getInterpolation((((float) count) / difference)) * 100) * count;
final int finalCount = ((initialValue > finalValue) ? initialValue - count : count);
handler.postDelayed(new Runnable() {
#Override
public void run() {
textview.setText(String.valueOf(finalCount));
}
}, time);
}
}
I think this project in github is what you want: https://github.com/sd6352051/RiseNumber
The RiseNumberTextView extends TextView and use the ValueAnimator to implement the rising number effect.
This is a Kotlin code for incrementing from initial value to final value over a duration of time. Here I have used duration of 5 sec.
fun animateTextView(initialValue: Int, finalValue: Int, textView: TextView) {
val valueAnimator = ValueAnimator.ofInt(initialValue, finalValue)
valueAnimator.duration = 5000 // 5 sec
valueAnimator.addUpdateListener { valueAnimator -> textView.text = valueAnimator.animatedValue.toString() }
valueAnimator.start()
}
use this code in Utilities and call the method accordingly with required parameters.
try this code..showing increment value with animation
public class MainActivity extends Activity implements AnimationListener {
private TextView textView;
AlphaAnimation fadeIn, fadeOut;
private static int count = 0, finalValue = 20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo);
textView = (TextView) findViewById(R.id.textView);
fadeIn = new AlphaAnimation(0.0f, 1.0f);
fadeOut = new AlphaAnimation(1.0f, 0.0f);
fadeIn.setDuration(1000);
fadeIn.setFillAfter(true);
fadeOut.setDuration(1000);
fadeOut.setFillAfter(true);
fadeIn.setAnimationListener(this);
fadeOut.setAnimationListener(this);
textView.startAnimation(fadeIn);
textView.startAnimation(fadeOut);
}
#Override
public void onAnimationEnd(Animation arg0) {
// TODO Auto-generated method stub
Log.i("mini", "Count:" + count);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
textView.setText("" + count);
}
});
if (count == finalValue) {
textView.setText("" + finalValue);
} else {
++count;
textView.startAnimation(fadeIn);
textView.startAnimation(fadeOut);
}
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
}
I am Trying to animate 3 images one after the other using value animator but i am not able to decide how to call the three handlers after regular intervals..Suppose there are 3 images and i m making three handlers for animating them.But i am able to bring the three images at a time but not one after the other at regular intervals.Please Help
This is my UpdateListener which i am calling from my handler
public void startAnimation_image(final ImageView aniView) {
animator = ValueAnimator.ofFloat(0, .8f);
animator.setDuration(Constants.ANIM_DURATION);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
int Low = 10;
int High = width-150;
int R = (int) ((Math.random() * (High - Low)) + Low);
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = ((Float) (animation.getAnimatedValue())).floatValue();
aniView.setTranslationX(R);
Log.e("mscale",150*mScale +"");
Log.e("value is", value+"");
aniView.setTranslationY((mDisplaySize.bottom + (150*mScale))*value);
x_point = aniView.getTranslationX();
y_point = aniView.getTranslationY();
}
});
animator.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {
}
#Override
public void onAnimationRepeat(Animator arg0) {
}
#Override
public void onAnimationEnd(Animator arg0) {
startAnimation();
}
#Override
public void onAnimationCancel(Animator arg0) {
}
});
animator.start();
}
This is one of my handler
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//int viewId = new Random().nextInt(STARS.length);
id = getApplicationContext().getResources().getIdentifier(STARS[0], "drawable",
getApplicationContext().getPackageName());
inflate = LayoutInflater.from(StarsActivity2.this);
img[0].setVisibility(ImageView.VISIBLE);
img[0].setImageResource(id);
mAllImageViews.add(img[0]);
LayoutParams animationLayout = (LayoutParams) img[0].getLayoutParams();
img[0].setLayoutParams(animationLayout);
Log.e("mHandler",img[0]+ "");
startAnimation_image(img[0]);
}
};
There are similaarly three handlers and three update listeners.. Please help...
You can delay an animation by offset ms by calling
animation.setStartOffset(offset);
So for three images with duration ANIM_DURATION, you can use the following values to start them sequentially (probably by passing them as a parameter to startAnimation_image())
// note: this is for illustrative purposes. You should put this in a loop
int firstOffset = 0 * ANIM_DURATION; // starts immediately
int secondOffset = 1 * ANIM_DURATION; // starts after the first animation is finished
int thirdOffset = 2 * ANIM_DURATION; // starts after the second animation is finished
// ... and so on.
I'm currently using Nine Old Androids to animate a RelativeLayout like a slider menu, which slides down form the top. I've tried in many ways, Can someone make a suggestion?
Here is the animation code:
private OnClickListener slideClick = new OnClickListener(){
#Override
public void onClick(View v) {
slideGroups.bringToFront();
if(!mPulledDown) {
ObjectAnimator oa = ObjectAnimator.ofFloat(slideGroups, "translationY", slideGroups.getHeight()-80);
oa.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {}
#Override
public void onAnimationRepeat(Animator arg0) {}
#Override
public void onAnimationEnd(Animator arg0) {
arrow.setImageResource(R.drawable.arrowup);
if(Application.getAndroidAPILevel() < 11) {
// only if pre 3.0 (api level 11)
Toast.makeText(FriendsActivity.this, String.format("api level %s",
Application.getAndroidAPILevel()), Toast.LENGTH_SHORT).show();
//RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) slideGroups.getLayoutParams();
// clear animation to prevent flicker
slideGroups.clearAnimation();
// set new "real" position of wrapper
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, slideGroups.getWidth());
//lp.addRule(RelativeLayout.BELOW, R.id.branchFinderIncludeHeader);
slideGroups.setLayoutParams(lp);
}
}
#Override
public void onAnimationCancel(Animator arg0) {}
});
oa.start();
}
else
{
ObjectAnimator oa = ObjectAnimator.ofFloat(slideGroups, "translationY", 0);
oa.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {}
#Override
public void onAnimationRepeat(Animator arg0) {}
#Override
public void onAnimationEnd(Animator arg0) {
arrow.setImageResource(R.drawable.arrowdown);
if(Application.getAndroidAPILevel() < 11) {
// only if pre 3.0 (api level 11)
Toast.makeText(FriendsActivity.this, String.format("api level %s",
Application.getAndroidAPILevel()), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onAnimationCancel(Animator arg0) {}
});
oa.start();
}
mPulledDown = !mPulledDown;
}
};
I just need something to work with sdk level 4 and newer. Currently, touching/tapping passes that event to the list underneath the slider when expanded. Please let me know if any other information is needed. slideGroups is the RelativeLayout. arrow is an imageview. groupsButton is a LinearLayout with text and an image button. groupsButton should be clickable; that's what expands and is supposed to collapse it.
Thanks in advance.
A few people have contributed by editing my question with solutions. I'd like to give them credit, but can't upvote an edit. For posterity, here is the solution that works for me.
int originalMarginLeft = 0;
int originalMarginTop = 0;
int originalMarginRight = 0;
int originalMarginBottom = 0;
int originalLeft = 0;
int originalTop = 0;
int originalRight = 0;
int originalBottom = 0;
int originalX = 0;
int originalY = 0;
int originalHeight = 0;
private OnClickListener slideClick = new OnClickListener(){
#Override
public void onClick(View v) {
slideGroups.bringToFront();
if(originalMarginLeft == 0) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) slideGroups.getLayoutParams();
originalMarginLeft = params.leftMargin;
originalMarginTop = params.topMargin;
originalMarginRight = params.rightMargin;
originalMarginBottom = params.bottomMargin;
originalLeft = slideGroups.getLeft();
originalTop = slideGroups.getTop();
originalRight = slideGroups.getRight();
originalBottom = slideGroups.getBottom();
originalHeight = params.height;
}
if(!mPulledDown) {
ObjectAnimator oa = ObjectAnimator.ofFloat(slideGroups, "translationY", originalHeight);
oa.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {}
#Override
public void onAnimationRepeat(Animator arg0) {}
#Override
public void onAnimationEnd(Animator arg0) {
arrow.setImageResource(R.drawable.arrowup);
if(Application.getAndroidAPILevel() < 11) {
slideGroups.clearAnimation();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(slideGroups.getWidth(), slideGroups.getHeight());
lp.leftMargin = originalMarginLeft;
lp.rightMargin = originalMarginRight;
slideGroups.setLayoutParams(lp);
}
}
#Override
public void onAnimationCancel(Animator arg0) {}
});
oa.start();
}
else
{
ObjectAnimator oa = ObjectAnimator.ofFloat(slideGroups, "translationY", -originalHeight+60);
oa.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {}
#Override
public void onAnimationRepeat(Animator arg0) {}
#Override
public void onAnimationEnd(Animator arg0) {
arrow.setImageResource(R.drawable.arrowdown);
if(Application.getAndroidAPILevel() < 11) {
slideGroups.clearAnimation();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(slideGroups.getWidth(), slideGroups.getHeight());
lp.leftMargin = originalMarginLeft;
lp.rightMargin = originalMarginRight;
lp.topMargin = originalMarginTop;
lp.bottomMargin = originalMarginBottom;
slideGroups.setLayoutParams(lp);
}
}
#Override
public void onAnimationCancel(Animator arg0) {}
});
oa.start();
}
mPulledDown = !mPulledDown;
}
};
I had an activity (say homeActivity) and when I start a new activity(say nextActivity) from my homeactivity i would like to give it an animation effect like appearing it from the bottom. Is it possible in android?
after call to startActivity, make call to overridePendingTransition with id's of xml defined animations, one for exiting activity, one for entering. See docs for this method here
You can prevent the default animation (Slide in from the right) with the Intent.FLAG_ACTIVITY_NO_ANIMATION flag in your intent.
i.e.:
Intent myIntent = new Intent(context, MyActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
context.startActivity(myIntent);
then in your Activity you simply have to specify your own animation.
TopListActivity topList;
Vector<BitmapDrawable> images;
int count = 0;
public AnimationAlphaTimer(TopListActivity _topList)
{
this.topList = _topList;
this.images = new Vector<BitmapDrawable>();
for (int i = 0; ; i++) {
// LOAD IMAGES HERE
}
if (this.images.size() > 0) {
this.topList.slide_0.setBackgroundDrawable(this.images.get(0));
if (this.images.size() > 1) {
this.topList.slide_1.setBackgroundDrawable(this.images.get(1));
}
}
this.count = 1;
}
public void launch()
{
if (this.images.size() >= 2) {
(new Timer(false)).schedule(this, 100);
}
}
#Override
public void run()
{
this.doit();
this.cancel();
}
private void doit()
{
if ((this.count % 2) == 0) {
AlphaAnimation animation = new AlphaAnimation(1.0f, 0.0f);
animation.setStartOffset(3000);
animation.setDuration(3000);
animation.setFillAfter(true);
animation.setAnimationListener(this);
this.topList.slide_1.startAnimation(animation);
} else {
AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setStartOffset(3000);
animation.setDuration(3000);
animation.setFillAfter(true);
animation.setAnimationListener(this);
this.topList.slide_1.startAnimation(animation);
}
}
public void onAnimationEnd(Animation animation)
{
if ((this.count % 2) == 0) {
this.topList.slide_1.setBackgroundDrawable(
this.images.get((this.count + 1) % (this.images.size()))
);
} else {
this.topList.slide_0.setBackgroundDrawable(
this.images.get((this.count + 1) % (this.images.size()))
);
}
this.count++;
this.doit();
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}}
try this i think it will work.