Stack Runnables in a queue with ThreadFactory - java

I have a method that takes 4 second to execute, if the user calls it again before it ended than it will refresh, I want to only start the new one after the last one has finished, putting them in a queue.
I've read the documentation, but I still don't know how to implement it, can someone provide an example please?
Code
my method:
public void popClassAdded(int amount){
classAddedText.setText(getString(R.string.you_earned) + amount + " ");
setIn = new AnimatorSet();
setIn.playTogether(
Glider.glide(Skill.QuintEaseOut, 200, ObjectAnimator.ofFloat(classAddedLayout, "translationY", -50, 165))
);
setIn.setDuration(1200);
classAddedLayout.setVisibility(View.VISIBLE);
setIn.start();
classAddedLayout.postDelayed(new Runnable(){
public void run(){
AnimatorSet set = new AnimatorSet();
set.playTogether(Glider.glide(Skill.CubicEaseInOut, 200, ObjectAnimator.ofFloat(classAddedLayout, "translationY", 165, -50)));
set.setDuration(1200);
set.start();
set.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) { }
#Override
public void onAnimationEnd(Animator animation) {
classAddedLayout.setVisibility(View.GONE);
}
#Override
public void onAnimationCancel(Animator animation) { }
#Override
public void onAnimationRepeat(Animator animation) { }
});
}
},2000);
shopPrefs.edit().putInt("coins", amount + shopPrefs.getInt("coins", 0)).apply();
}
Calling it:
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//may get clicked more than once in an interval or 4 seconds
((Activity_Main)getActivity()).popClassAdded(100);
}
});

Related

How to put Text after Animation is running?

I want to make some text appear after an animation like rotating for 2min.
I tried using method like isRunning() in Animator but didn't work.
ObjectAnimator object = ObjectAnimator.ofFloat(ima, "rotation", 1080);
object.setInterpolator(new AccelerateInterpolator());
object.setDuration(1000);
object.setRepeatCount(0);
object.start();
boolean bo = object.isRunning();
while(!bo) {
Random ran = new Random();
int count = ran.nextInt(10);
String str = Integer.toString(count);
text.setText(str);
bo = true ;
}
Take your animation object and add animation listener to it
rotatationAnimation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
**// set your text visisbilty **
}
});
To listen to an ObjectAnimator, just add the following code :
object.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationEnd(Animator animator) {
/*make your text appear*/
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
I hope I could have helped you!

how to avoid memory leakage from an animated GIF

I'm receiving URLs from server which should be translated to GIFs, These GIFs should animate whenever the user clicks on them or when receiving a response from any of the users, everything is working fine however when receiving lots of them I experience memory leakage, it doesn't go out of memory however the memory keeps increasing constantly and keeps facing hickups, please advise what can be done in order to avoid having them on the memory, I've tried initializing the animImageView with null however still the same attitude, please advise what can be done.
public void getGifts() {
Communicator.getInstance().on("sendGift", new Emitter.Listener() {
Animation anim;
EmojiModel emojiUrl = new EmojiModel();
String url = emojiUrl.getUrlFile();
#Override
public void call(Object... args) {
JSONDictionary response = (JSONDictionary) args[0];
url = (String) response.get("giftUrl");
Runnable runnable = new Runnable() {
#Override
public void run() {
animImageView = null;
animImageView = new ImageView(getApplicationContext());
animImageView.setVisibility(View.VISIBLE);
Glide.with(getApplicationContext())
.load(url)
.thumbnail(0.1f)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.crossFade()
.override(900,400)
.into(animImageView);
final RelativeLayout relativeLayout =
(RelativeLayout)findViewById(R.id.imageView_relative);
anim =
AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.move_to_right_anim);
relativeLayout.addView(animImageView);
animImageView.startAnimation(anim);
StreamActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
anim.setAnimationListener(new
Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
anim =AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.move_to_right_anim);
animImageView.startAnimation(anim);
}
#Override
public void onAnimationEnd(Animation animation) {
animImageView = null;
}
#Override
public void onAnimationRepeat(Animation animation) {
animImageView = null;
}
});
}
});
}
};
mhandler.post(runnable);
}
});
}
This has been resolved by adding relativeLayout.removeAllViewsInLayout(); before adding the view

how to disable button for some for example 2 minutes in android studio

I want complete code to disable a Button for some time for example 2 minutes in Android Studio. Thank you for help.
protected void onclick(View v){
bwasta = (Button) findViewById(R.id.btDes);
new CountDownTimer(10000, 10) { //Set Timer for 10 seconds
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
bwasta.setEnabled(true);
bwasta.setEnabled(false);
}
}.start();
This might help you out.
Button bwasta = (Button) findViewById(R.id.btDes);
bwasta.setEnabled(false);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2*
60*
1000);//min secs millisecs
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
YourActivityName.this.runOnUiThread(new Runnable() {
#Override
public void run() {
bwasta.setEnabled(true);
}
});
}
}).start();
DO NOT RELY ON Thread.sleep()
Actually, there is already a Question and an Answer on SO regarding the inaccuracy of Thread.sleep()(as per the OP's experience) here.
The answer then favors the accuracy of a ScheduledThreadPoolExecutor using the schedule() method.
Do the following:
Button bwasta = (Button) findViewById(R.id.btDes);
bwasta.setEnabled(false);
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.schedule(new new Runnable() {
#Override
public void run() {
YourActivityName.this.runOnUiThread(new Runnable() {
#Override
public void run() {
bwasta.setEnabled(true);
}
});
}
}, 2, TimeUnit.MINUTES);
You can use mHandler.postDelayed(mRunnable, mTime) function to achieve this
Button bwasta = (Button) findViewById(R.id.btDes);
bwasta.setEnabled(false);
bwasta.postDelayed(new Runnable() {
public void run() {
bwasta.setEnabled(true);
}
}, 2*60*1000);

Repeat specific action X number of times in Android

So I want certain action to be performed X number of times, depends on how many times user wants it. User selection will be selected from a TextView string which is set up with this code:
homeScreenPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dodajInterval();
homeScreenMinus.setEnabled(counter > 0);
}
});
homeScreenMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
oduzmiInterval();
homeScreenMinus.setEnabled(counter > 0);
}
});
}
private void oduzmiInterval() {
counter--;
brojIntervala.setText(Integer.toString(counter));
}
private void dodajInterval() {
counter++;
brojIntervala.setText(Integer.toString(counter));
}
Those are basicly two buttons that increment or decrement value of TextView.
The action I want to perform X times is this:
public void homeScreenStart(View view) {
linearniLayoutSetup.setVisibility(View.GONE);
new CountDownTimer(seekBarTimerDelay.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_trci));
}
}.start();
}
private void countDownTimerTrci() {
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
countDownTimerHodaj();
}
}.start();
}
private void countDownTimerHodaj(){
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
new CountDownTimer(seekBarIntervaliNiskogIntenziteta.getProgress() * 1000 + 100, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.colorAccent));
textViewTimerTrciHodajBlaBla.setText("Done!");
}
}.start();
}
So it is combination of 3 seekbars, or timers, one running after another and then they should run as many times as user selects.
The problem is, I have no idea how to set this up, and I need that first block of code in timers to run just once, and those 2 methods below it to run X times.
How can I do it?
Unless I am missing something couldn't you just wrap your code in the action in a loop that references the current counter? You may need to block input so that the user can not modify the counter (unless you want them to) after execution has begun but that should be it.
public void homeScreenStart(View view) {
linearniLayoutSetup.setVisibility(View.GONE);
CountDownTimer firstCountDown = new CountDownTimer(seekBarTimerDelay.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_trci));
}
}
CountDownTimer secondCountDown = new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
countDownTimerHodaj();
}
}
CountDownTimer thirdCountDown = new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
countDownTimerHodaj();
}
}
for (int i = 0; i < counter; i++) {
firstCountDown.start();
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
secondCountDown.start();
thirdCountDown.start();
}
}
Should work for you

Put Animation delay on ImageViews and TextViews that belongs to 1 Animation set

I have already a rough idea about how to do this and I think it is by making 2 or more animation set per Image View or Text View but the code would be to long. Is there a way in which I could minimize the codes? Here is the code for every Image View and Text View:
AnimationSet setA = new AnimationSet(true);
fadeIn1.setDuration(1000);
setA.addAnimation(fadeIn1);
TranslateAnimation Trans1 = new TranslateAnimation(270, 0, 0, 0);
Trans1.setDuration(1000);
setA.addAnimation(Trans1);
ImageView1.startAnimation(setA);
//how do i place delay here??
ImageView2.startAnimation(setA);
//how do i place delay here??
TextView1.startAnimation(setA);
//how do i place delay here??
TextView2.startAnimation(setA);
//how do i place delay here??
setA.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
ImageView1.clearAnimation();
ImageView2.clearAnimation();
TextView1.clearAnimation();
TextView2.clearAnimation();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
You can make delay by using handlers..
eg:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
ImageView1.startAnimation(setA);
}
}, 2000);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
ImageView2.startAnimation(setA);
}
}, 4000);

Categories