How to animate multiple objects one by one after some intervals android
i am using this code for animation
for (int y = 0; y < 10; y++) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
Toast.makeText(ProjectFirstActivity.this, y + "",
Toast.LENGTH_SHORT).show();
ObjectAnimator oa = ObjectAnimator.ofFloat(myimageview[y],
"translationY", 0, -200);
oa.setDuration(1000);
oa.start();
}
});
}
but it is animating all in one go but i want one by one animation of my imageview please help
No need to use Threads and Handlers. Instead of that use,
objectAnimator.setStartDelay(delay);
Using that you can stop that animation for the respective 'delay'
Try this code..
int delay = 1000;
for (int y = 0; y < 10; y++) {
Toast.makeText(ProjectFirstActivity.this, y + "",
Toast.LENGTH_SHORT).show();
ObjectAnimator oa = ObjectAnimator.ofFloat(myimageview[y],
"translationY", 0, -200);
oa.setDuration(1000);
oa.setStartDelay(delay);
oa.start();
delay = delay+1000;
}
You can use for loop to generate AnimatorSet and then play them sequentially using set.playSequentially(yourAnimatorSetListHere);
I haven't used list in below mentioned snippet.
AnimatorSet decSet = new AnimatorSet();
decSet.playTogether(
ObjectAnimator.ofArgb(mTextSlidetoCancel, "visibility", View.GONE, View.VISIBLE),
ObjectAnimator.ofArgb(mBtnMicActive, "visibility", View.GONE, View.VISIBLE),
ObjectAnimator.ofArgb(mChronometer, "visibility", View.GONE, View.VISIBLE));
decSet.setDuration(125);
AnimatorSet decSet2 = new AnimatorSet();
decSet2.playTogether(
ObjectAnimator.ofArgb(mBtnAttach, "visibility", View.VISIBLE, View.GONE),
ObjectAnimator.ofArgb(mBtnEmoji, "visibility", View.VISIBLE, View.GONE),
ObjectAnimator.ofArgb(mEditTExt, "visibility", View.VISIBLE, View.GONE)
);
decSet2.setDuration(125);
AnimatorSet set = new AnimatorSet();
set.playSequentially(decSet2,decSet);
set.start();
Try out this way!
public Integer[] Imgid = {R.drawable.anim2, R.drawable.anim3,
R.drawable.anim4, R.drawable.anim5}; // your image array.
Animation anim;
Handler handler;
ImageView iv;
int count;
Runnable galleryAnimRunnable;
Inside onCreate
iv= (ImageView)findViewById(R.id.imagetype);
handler = new Handler();
galleryAnimRunnable = new Runnable() {
public void run() {
if(count==Imgid.length){
//do any action
}
else{
anim = AnimationUtils.loadAnimation(AnimationScreen.this, R.anim.fade_out); // load your desire animation.
iv.setBackgroundResource(Imgid[count]);
iv.setAnimation(anim);
count++;
handler.postDelayed(galleryAnimRunnable, 300); //set your desire delay time.
}
}
};
Your sleep call isn't helping because when one posted UI job goes to sleep, then next one starts and goes to sleep immediately following that, and so on. Then the first job wakes up and runs, followed closely by the second job awakening and running, etc.
If you want the sleep to help you need to wait before posting each job, which could be as simple as something like the following:
for (int y = 0; y < 10; y++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(ProjectFirstActivity.this, y + "",
Toast.LENGTH_SHORT).show();
ObjectAnimator oa = ObjectAnimator.ofFloat(myimageview[y],
"translationY", 0, -200);
oa.setDuration(1000);
oa.start();
}
});
}
EDIT: Although the above explains why you were having problems, I would recommend going with something like the answer posted by Jgdsh Seerm using setStartDelay().
Try this way!
ImageView image1;
public int currentimageindex1=0;
Timer timer;
TimerTask task;
private Animation animation1;
private Animation animation2;
int img[] = {R.drawable.aa, R.drawable.bb,
R.drawable.cc,R.drawable.dd,R.drawable.ee,R.drawable.ff,R.drawable.gg,
R.drawable.hh};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler mHandler = new Handler();
// Create runnable for posting
final Runnable mUpdateResults = new Runnable() {
public void run() {
AnimateandSlideShow();
}
};
int delay = 1000; // delay for 1 sec.
int period = 4000; // repeat every 4 sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
mHandler.post(mUpdateResults);
}
}, delay, period);
}
public void onClick(View v) {
finish();
android.os.Process.killProcess(android.os.Process.myPid());
}
/**
* Helper method to start the animation on the splash screen
*/
private void AnimateandSlideShow() {
image1 = (ImageView)findViewById(R.id.imageView1);
image1.setImageResource(img[currentimageindex1%img.length]);
currentimageindex1++;
}
Related
If the user (in my quizgame) chooses the false answer, the button with the correct answer should blink green.
So far i did it like this:
if(answerTrue)
for (int i = 0; i < 2000; i = i + 250) {
handler.postDelayed(rbl_blinkNormal, i);
i = i + 250;
handler.postDelayed(rbl_blinkGreen, i);
}
And the runnables:
Green:
rbl_blinkGreen= new Runnable() {
#Override
public void run() {
btn_richtig.setBackgroundResource(R.drawable.color_green_btn);
}
};
Normal:
rbl_blinkNormal= new Runnable() {
#Override
public void run() {
btn_richtig.setBackgroundResource(R.drawable.color_black_btn);
}
};
It works fine but like this Im calling the postDelayed() every 250ms. May this impact my application performance and is there any better way to do this?
You can animate your button once you set its color to say GREEN. I mean,
if(answerTrue){
// Set the color of the button to GREEN once.
// Next, animate its visibility with the set color - which is GREEN as follows:
Animation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(50); //You can manage the blinking time with this parameter
anim.setStartOffset(20);
anim.setRepeatMode(Animation.REVERSE);
anim.setRepeatCount(Animation.INFINITE);
button.startAnimation(anim);
}
Similarly, you can animate the other button and stop animation when you feel like.
Source: Blinking Text in android view
If you want to blink the image only, here is an example.
Button bt_notes = (Button) findViewById(R.id.bt_notes);
int bt_notes_blink = 0;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
int DrawableImage[] = {R.drawable.picto_keys, R.drawable.picto_blank};
Resources res = getApplicationContext().getResources();
bt_notes.setCompoundDrawablesWithIntrinsicBounds(null, null, null, res.getDrawable(DrawableImage[bt_notes_blink]));
bt_notes_blink++;
if (bt_notes_blink == 2) { bt_notes_blink = 0; }
handler.postDelayed(this, 500);
}
});
}
}, 0);
I have an ImageButton and I want to make it fade in randomly and fade out after some time.
How can I do this?
With a thread? with a service? with something else?
Sorry if it is a very novice question. Thank you
This will fade in/out the imageButton in random interval of 1-5 seconds.
private boolean fadeIn = false;
private final Random rand = new Random();
...
final Handler handler = new Handler(Looper.getMainLooper());
final Runnable runnable = new Runnable() {
#Override
public void run() {
imageButton.animate().alpha(fadeIn ? 1.0f : 0.0f).setDuration(500).withEndAction(new Runnable() {
#Override
public void run() {
fadeIn = !fadeIn;
}
});
handler.postDelayed(this, randInt(1000, 5000));
}
};
handler.post(runnable);
...
public int randInt(int min, int max) {
return rand.nextInt((max - min) + 1) + min;
}
#Override
protected void onDestroy() {
handler.removeCallbacks(runnable);
super.onDestroy();
}
I am trying to create a small animation which changes smoothly the background color. My problem is that it only shows the last value (100, that means it directly goes to a red background). I don't know why my created while-loop doesn't actualize every value (so that it would show a smoothly color animation)
New code (which almost works, but Idk how to stop the animation)
imageButton_info.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
final Handler handler = new Handler();
Runnable ChangeBackgroundRunnable = new Runnable() {
#Override
public void run() {
number++;
float[] hsvColor = {0, 1, 1};
hsvColor[0] = 360f * number / 100;
color.setBackgroundColor(Color.HSVToColor(hsvColor));
handler.postDelayed(this, 80);
if (number >=100)
number = 1;
}
};
number = 0;
handler.removeCallbacks(ChangeBackgroundRunnable);
handler.postDelayed(ChangeBackgroundRunnable, 0);
}
});
Code:
public void onClick(View v){
try {
while (number<=100) {
number=number+1;
float[] hsvColor = {0, 1, 1};
hsvColor[0] = 360f * number / 100;
color.setBackgroundColor(Color.HSVToColor(hsvColor));
Thread.sleep(10);
}
}catch(Exception e){
//New exception
Log.e("Camera Error!",e.getMessage());
}
Thank you for your answer in advance...
When you change something in the UI, it doesn't happen immediately. Instead, it posts a message to the Looper on the UI thread. When control returns to the looper (when you're done with whatever function the framework called), it will process all the messages on the Looper, until it eventually processes the redraw request. Then it will draw. So if you're looping in onClick, you will not get any updates to the screen. If you want something to happen in 10ms, post a delayed message to a Handler and update the UI in that thread.
Side note: NEVER EVER sleep on the UI thread. The reason is that no input or draw commands can be processed if you're not returning control to the Looper. So your app becomes unresponsive. If you do it long enough, it can even cause the framework to kill your app for being unresponsive.
A better way to do this would be to use an Android animation. I stole the code for this from here
int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(250); // milliseconds
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animator) {
textView.setBackgroundColor((int) animator.getAnimatedValue());
}
});
colorAnimation.start();
Wrapped the answers posted by #gabe-sechan and #jesse-buss
ValueAnimator support from devices SDK above HONEYCOMB. So below that SDK level we'll use #gabe-sechan suggestion. Check the below code.
private void executeBackgroundChange() {
// Handler and runnable to run the animation in devices sdk below honeycomb.
mHandler = new Handler();
mChangeBackgroundRunnable = new Runnable() {
#Override
public void run() {
number++;
float[] hsvColor = {0, 1, 1};
hsvColor[0] = 360f * number / 100;
mContainer.setBackgroundColor(Color.HSVToColor(hsvColor));
mHandler.postDelayed(this, 500);
if (number == 100)
number = 0;
}
};
number = 0;
mHandler.removeCallbacks(mChangeBackgroundRunnable);
mHandler.postDelayed(mChangeBackgroundRunnable, 0);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void executeBackgroundChangeUsingValueAnimator() {
colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), getResources().getColor(R.color.red), getResources().getColor(R.color.blue));
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(final ValueAnimator animator) {
mContainer.setBackgroundColor((Integer) animator.getAnimatedValue());
}
});
colorAnimation.setRepeatCount(ValueAnimator.INFINITE);
colorAnimation.setDuration(10 * 1000);
colorAnimation.start();
}
Add the below method and to stop the animation on click of something call the below method.
private void stopBackgroundChangeAnimation() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
if (colorAnimation != null && colorAnimation.isRunning())
colorAnimation.end();
} else {
if (mHandler != null && mChangeBackgroundRunnable != null)
mHandler.removeCallbacks(mChangeBackgroundRunnable);
}
}
Check the github project for reference.
Try to use runOnUiThread
public void onCreate(Bundle savedInstanceState) {
res = getResources();
super.onCreate(savedInstanceState);
setContentView(R.layout.xyz);//**Works**/
handler.postDelayed(runnable, 10);
}
private Runnable runnable = new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run()
{
try {
while (number<=100) {
number=number+1;
float[] hsvColor = {0, 1, 1};
hsvColor[0] = 360f * number / 100;
color.setBackgroundColor(Color.HSVToColor(hsvColor));
}
}catch(Exception e){
//New exception
}
}
});
}
}
I m trying to increase the speed (duration) for the setmButton when mButton is clicked, but no results.I need to make the mButton to move from x=0 to x=100 in less seconds so i will increase the speed. The mButon animation starts from x=0 and move to x=100 in duration=10000, when i click on it i want the mButton to increase the speed to the final position.
Thank you
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void animationA() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
final ImageButton mButton = (ImageButton)findViewById(R.id.Button );
assert mButton != null;
mButton.setBackgroundResource(R.drawable.Button);
ObjectAnimator mButtonAnimation= ObjectAnimator.ofFloat(mButton , "translationX", 0, -2100);
mButtonAnimation.setDuration(11000);
mButtonAnimation.setStartDelay(50);
mButtonAnimation.setRepeatCount(ObjectAnimator.INFINITE);
mButtonAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
ObjectAnimator mButtonAnimation1 = ObjectAnimator.ofFloat(mButton, "alpha", 0, 1);
mButtonAnimation1 .setDuration(90);
mButtonAnimation1 .setInterpolator(new AccelerateDecelerateInterpolator());
final AnimatorSet setmButton = new AnimatorSet();
setmButton .playTogether(mButtonAnimatiea, mButtonAnimation1 );
//setmButton .setFillAfter(true);
setmButton.start();
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Handler handlermButton = new Handler();
handlermButton.postDelayed(new Runnable() {
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
#Override
public void run() {
setmButton.setDuration(500);
}
}, 100);
}
});
}}, 100); }
You could use ACCELERATE interpolator if you want an higher speed level near from the end or simply set the duration to a lower value so the animation will be faster.
I wanted to display 9 images one after the other. I have included the 9 images as an array:
imageHolders = new ArrayList<ImageView>();
imageHolders.add((ImageView) view.findViewById(R.id.imgOne));
imageHolders.add((ImageView) view.findViewById(R.id.imgTwo));
imageHolders.add((ImageView) view.findViewById(R.id.imgThree));
imageHolders.add((ImageView) view.findViewById(R.id.imgFour));
imageHolders.add((ImageView) view.findViewById(R.id.imgFive));
imageHolders.add((ImageView) view.findViewById(R.id.imgSix));
imageHolders.add((ImageView) view.findViewById(R.id.imgSeven));
imageHolders.add((ImageView) view.findViewById(R.id.imgEight));
imageHolders.add((ImageView) view.findViewById(R.id.imgNine));
This is what I have tried:
public void handleMessage(Message msg) {
int currentImage = 0;
int nextImage = 0;
// Logic to change the images
for (final ImageView imageView : imageHolders) {
currentImage = Integer.parseInt(imageView.getTag().toString());
if (currentImage > 1) {
nextImage = currentImage - 1;
} else {
nextImage = 9;
}
imageView.setTag(""+nextImage);
new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
imageView.setVisibility(VISIBLE);
}
}.start();
}
super.handleMessage(msg);
}
}
There is a delay between the first and the second images. I am not able to introduce a delay between the rest. I have no clue about introducing the delay. Any suggestions would be appreciated.
you could just use AnimationDrawable which does this for you , and allows you to set a duration of time (in milliseconds) using android:duration attribute .
The AnimationDrawable is probably the best answer, but for another solution you can look at AsyncTask.
http://developer.android.com/reference/android/os/AsyncTask.html
Then, you can in the background just sleep for some set amount of time, then display the next image.
You may want an event though to handle when this task is done, and in the listener you call the next one.
If you want to make just a simple static animation (all images at the same position) you can use AnimationDrawable but you can't easly change it dynamically - like change speed or something.
I just wrote a simple class for this so I can set multiple animations for one ImageView and change speed.
public class ImageSequence extends ImageView {
ArrayList<Drawable> draws = new ArrayList<Drawable>();
ArrayList<Integer> bnds = new ArrayList<Integer>(); //bounds of sequences - index of first and last frame.
ArrayList<String> names = new ArrayList<String>(); //sequences names.
Timer timer = new Timer(true);
TimerTask task;
int p = -1; //current playback position.
int cS = -1; //current sequence.
public ImageSequence(Context context) {
super(context);
createTask();
}
public void addSequence(String name, int[] res){
names.add(name);
bnds.add(draws.size());
bnds.add(draws.size() + res.length - 1);
for (int i = 0; i < res.length; i++){
draws.add(getContext().getResources().getDrawable(res[i]));
}
}
public void play(String sequence, float speed){
cS = -1;
for(int i = 0; i < names.size(); i++){
if(names.get(i) == sequence){ cS = i; break;}
}
if(cS<0) return;
p = -1;
task.run();
task.cancel();
if(speed <= 0) return;
createTask();
timer.schedule(task, (long) (1000/speed), (long) (1000/speed));
}
public void stop(){
task.cancel();
}
public void cancelTimer(){
timer.cancel();
}
private void createTask() {
task = new TimerTask(){
public void run() {
p++;
mHandler.obtainMessage(1).sendToTarget();
}
};
}
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
int l = p;
if(l > bnds.get(cS*2+1) || l < bnds.get(cS*2)) l = bnds.get(cS*2);
p = l;
ImageSequence.this.setImageDrawable(draws.get(l));
}
};
}
From outside you can use it like this:
seq.addSequence("orange", new int[]{R.drawable.ic_oval_diode_orange, R.drawable.ic_oval_diode_off});
seq.addSequence("green", new int[]{R.drawable.ic_oval_diode_green, R.drawable.ic_oval_diode_off});
seq.addSequence("red", new int[]{R.drawable.ic_oval_diode_red, R.drawable.ic_oval_diode_off});
seq.play("red", 4);
I'm not really experienced in Android and Java but it works and it do the job for me. Hope it will help someone.