I am having a really hard time trying to solve this problem :
I programmed an app that allows user to get rid of some colored squares on the screen. In my class coloredSquare, I have a method like this :
public void appearance(){
setLayoutParams(new RelativeLayout.LayoutParams(side/ 10, side/ 10));
final int[] count = {1};
final Runnable run = new Runnable() {
#Override
public void run() {
setLayoutParams(new RelativeLayout.LayoutParams(count[0] * side/ 50, count[0] * side/ 50));//View grows of 1/50 of its final size
if (count[0] < 50){
handler.postDelayed(this, 20);
} else {
setClickable(true);//When done
}
count[0]++;
}
};
handler = new Handler();
handler.postDelayed(run, 10);
}
When running on my Samsung Galaxy S4 mini, it's working juste fine.
But for instance, it does not work on the Wiko Highway 4G or on an emulator 1080x1920 and I can't understand why.
When I say that's not working : The view appears and grows but when it grows, every little view that was here before the postDelayed stays there.
And when I try to make them disappear by tapping on it, it shrinks well but all the other bigger views (before postDelayed) stay there too.
If you do not understand there, you will on the timer below.
In the meantime, I got a very simple timer like this :
final java.util.Timer t = new java.util.Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(termine){
t.cancel();
}
if(seconds == 0){
vCoul.setText(String.valueOf(minutes) + ":00");
} else if (seconds < 10) {
vCoul.setText(String.valueOf(minutes) + ":0" + String.valueOf(seconds));
} else {
vCoul.setText(String.valueOf(minutes) + ":" + String.valueOf(seconds));
}
seconds -= 1;
if(seconds == -1){
seconds = 59;
minutes=minutes-1;
}
}
});
}
}, 0, 1000);
But every second, the new time is overlapping the former one.
Sorry for the long post, thanks in advance for your answer!
I figured this out some months ago but I hope this answer will help others.
I didn't put any background in the Activity so on most of samsung devices, there were no issues since Samsung handle just fine the no background activities.
Though, on several Wiko and Archos devices, you have to put a background (like background:#000000) so that you can move views smoothly upon it.
Related
I have a problem with the progress bar, I have created several progress bars and I want to fill the first one with a specific time interval then after it done the second one start filling, I've done the first one like this
final ProgressBar pb_first = findViewById(R.id.Progressbar_first);
*
*
*
pb_first.setMax(10);
pb_first.setProgress(0);
final int[] currentProgress1 = {0};
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
currentProgress1[0] += 1;
pb_first.setProgress(currentProgress1[0]);
if(currentProgress1[0] != 10){
new Handler().postDelayed(this,1000);
}
else{
Toast.makeText(MainActivity.this, "The first step is OVER!!", Toast.LENGTH_LONG).show();
}
}
}, 1000);
but when I try to make the second one inside the else statement it won't work, I even tried to create an integer that changes when the above code is finished "in the else statement", and create an if-statement if(index == 2){} but it did not work as well, the app just stucks when starting it. Anyway to fix this?
I only managed to change between 2 images but I would like to change more than 2 images. I am creating a fitness application where each exercise is 30 seconds long, after 30 seconds, the next exercise starts. Each workout has about 5 exercises but I am only able to change between 2 images. Currently, after the timer hits 30 seconds, it will change to the next image but the timer stops there. I heard that I need to use array and loop but I am not sure how to... Can somebody help me? Your help will be greatly appreciated as my submission is due in 5 days ><
private void startTimer(){
countDownTimer = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDowntText();
}
#Override
public void onFinish() {
exercise_image.setImageResource(R.drawable.lunges);
exercise_name.setText("Alternate Lunges");
}
}.start();
mTimerRunning = true;
}
private void updateCountDowntText(){
int seconds = (int) (mTimeLeftInMillis / 1000) % 30;
String timeLeft = String.format(Locale.getDefault(), "%02d", seconds);
timerValue.setText(timeLeft);
}
if your images are in R.drawables. then simply store the int reference in your array and then load that such as below,
private int[] yourarray = {
R.drawable.star_00, //star_00 is image name here
R.drawable.star_01,
R.drawable.star_02,
};
Then when you want to load an image and draw to your imageview you do something like this from your Activity.
Drawable d = getResources().getDrawable(yourarray[n]);
Then call the setImageDrawable on ImageView. So:
yourImageView.setImageDrawable(d);
I'm working on this android app...and I have a textview, where I'd like to count UP. In this textview I have the statement "This page was refreshed X seconds ago". Every 20 seconds I'd like it to restart its countup from 0.
I've implemented a function which uses the ValueAnimator class. However, I'm not sure how to make the ValueAnimator increase the integer value by 1 every second. I'd like it to count up like a clock's second hand 1...2..3...4..5......20. Right now its counting up incredibly fast...and I want to slow it waaayyyy down. 1 count per second.
Please how do I do this? I've looked at some of the method calls for ValueAnimator, and I'm not sure how to slow it down...right now it's so fast.
Also, where would I add a method call, lets say, everytime the counter gets to 20 seconds? Lets say I want to call refreshView() when it gets to 20, before it starts all over.
Thank you for your time, and thanks for your help.
The ValueAnimator class:
https://developer.android.com/reference/android/animation/ValueAnimator
In my method I have:
ValueAnimator valueAnimator = ValueAnimator.ofInt(initialValue, finalValue);
valueAnimator.setDuration(10000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
textview.setText("This page was refreshed " + valueAnimator.getAnimatedValue().toString() + " seconds ago");
}
});
valueAnimator.start();
// Repeat 100 times
valueAnimator.setRepeatCount(100);
ValueAniamtor is used for animation. Animation are refreshed at very high rate. I don't think that you can count seconds with a valueAnimator.
In one of my apps i use a Timer to refresh periodically a textView.
final TextView textview=findViewById(R.id.tv);
new Timer().scheduleAtFixedRate(new TimerTask() {
int value=0; //start at 0
#Override
public void run() {
value++ ;
runOnUiThread(new Runnable() { //only the main thread can touch his views
#Override
public void run() {
textview.setText("This page was refreshed " + value + " seconds ago"); //refresh text
}
});
}
}, 0, 1000); //reschedule every 1000 milliseconds
}
Sorry I am a noob I've read countless tutorials about making a simple timer and was wondering why it doesn't work until I noticed it is the while-loop causing the issue o.O I have removed it and then it works but only 1 time I need to use the loop though so the movement finishes :C
Heres the code:
old_x is the coordinate from an ImageView and new_x from the onTouch Event, maybe the problem because I am casting them as an int? I don't know what I need to do so it works please help O:
while(old_x != new_x)
{
timedMoveIV(100);
old_x = (int)img.getX();
}
It calls this method which works if I do it without the loop.
public void timedMoveIV(int time_ms)
{
//sleep for time_ms milliseconds
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
if(new_x > img.getX())
{
img.setX(img.getX() + 1);
}
else
{
img.setX(img.getX() - 1);
}
}
}, time_ms);
}
Your main problem is that your loop doesn't take a break, so it's constantly running the function, posting a gazillion runnables.
What you want to do is make the runnable call itself after another 100 ms. Take a look at this example:
if(old_x != new_x)
timedMoveIV(100);
Here you simply call the function once. After that, you let the posted runnable decide whether or not it needs to move again:
public void timedMoveIV(final int time_ms)
{
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run()
{
if(new_x > img.getX())
img.setX(img.getX() + 1);
else
img.setX(img.getX() - 1);
// if not in position, call again
if((int)img.getX() != new_x)
timedMoveIV(time_ms);
}
}, time_ms);
}
It should stop once img.getX() == new_x. Notice the cast to int, though, because if you leave it out, you might get some oscillation as it gets within a pixel of the destination.
This assumes that new_x is an int. If it's a float as well, you should either cast both to int to compare, or compare them to a minimum threshold. For instance, if there's less than 0.5 difference, treat it as "done".
Hi im a newbie in Android & java lang.
i have this code that tells you how long have you been playing.
the code works fine, except when the screen turns off or when the user press the power button (sleep mode) it stop working.
can any one suggest a simple code to keep my time counting even when the screen is off or in sleep mode. Thanks...
public class test extends Activity
{
Handler mHandler = new Handler();
Runnable mUpdateTime = new Runnable()
{
public void run()
{
sec += 1;
if(sec >= 60)
{
sec = 0;
min += 1;
if (min >= 60)
{
min = 0;
hour += 1;
}
}
playtime.setText(String.format("%02d:%02d:%02d", hour, min, sec));
mHandler.postDelayed(mUpdateTime, 1000);
}
};
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mHandler.postDelayed(mUpdateTime, 1000);
}
}
I would suggest not counting the time, rather setting a start time and then subtracting that from the current to get the elapsed time.
A Chronometer widget might solve your problems.
I would advise against any solution where you might have to count during sleep mode, since that will kill the user's battery life.