TextSwitcher not updating - android

So I have a TextSwitcher that I want to update every second with the number of seconds it has been since the activity opened. Here is my code
public class SecondActivity extends Activity implements ViewFactory
{
private TextSwitcher counter;
private Timer secondCounter;
int elapsedTime = 0;
#Override
public void onCreate(Bundle savedInstanceState)
{
// Create the layout
super.onCreate(savedInstanceState);
setContentView(R.layout.event);
// Timer that keeps track of elapsed time
counter = (TextSwitcher) findViewById(R.id.timeswitcher);
Animation in = AnimationUtils.loadAnimation(this,
android.R.anim.fade_in);
Animation out = AnimationUtils.loadAnimation(this,
android.R.anim.fade_out);
counter.setFactory(this);
counter.setInAnimation(in);
counter.setOutAnimation(out);
secondCounter = new Timer();
secondCounter.schedule(new TimerUpdate(), 0, 1000);
}
/**
* Updates the clock timer every second
*/
public void updateClock()
{
//Update time
elapsedTime++;
int hours = elapsedTime/360;
int minutes = elapsedTime/60;
int seconds = elapsedTime%60;
// Format the string based on the number of hours, minutes and seconds
String time = "";
if (!hours >= 10)
{
time += "0";
}
time += hours + ":";
if (!minutes >= 10)
{
time += "0";
}
time += minutes + ":";
if (!seconds >= 10)
{
time += "0";
}
time += seconds;
// Set the text to the textview
counter.setText(time);
}
private class TimerUpdate extends TimerTask
{
#Override
public void run()
{
updateClock();
}
}
#Override
public View makeView()
{
Log.d("MakeView");
TextView t = new TextView(this);
t.setTextSize(40);
return t;
}
}
So basically, I have a Timer that every second adds another second and them formats the way I want to be displayed and set the text of the TextSwitcher, which I thought called makeView, but makeView only gets called once and the time stays as 00:00:01. Did I miss a step, I dont think this UI object is very well documented.
Thanks, Jake

You can only update the UI in the UI thread. So in your example you could do something like this.
private Handler mHandler = new Handler() {
void handleMessage(Message msg) {
switch(msg.what) {
CASE UPDATE_TIME:
// set text to whatever, value can be put in the Message
}
}
}
And call
mHandler.sendMessage(msg);
in the run() method of the TimerTask.
This is a solution to your current issue but there is probably a better way to do it without using TimerTasks.

Related

how do i add miliseconds option in this code?

I am learning android. I made this stopwatch app work from my reference book.It only shows Hour:minutes:seconds but I want to add milliseconds right to the seconds.how do I do that.
code::-
public class StopWatchActivity extends AppCompatActivity {
int seconds;
boolean running;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stop_watch);
runTimer();
}
public void startTimer(View view){
running = true;
}
public void stopTimer(View view){
running = false;
}
public void resetTimer(View view){
running = true;
seconds = 0;
}
public void runTimer(){
final TextView textView = (TextView) findViewById(R.id.timer);
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
int hours = seconds / 3600;
int minutes = (seconds % 3600) / 60;
int sec = seconds % 60;
String time = String.format("%d:%02d:%02d", hours,
minutes,sec);
textView.setText(time);
if(running) {
seconds++;
}
handler.postDelayed(this, 1000);
}
});
}
}
The first step would be to change the field seconds to milliSeconds because you want to keep track of that TimeUnit.
When restarting your handler with handler.postDelayed(this, 1000); define 1 millisecond as delay instead of 1000 (= 1 Second) like this handler.postDelayed(this, 1); then you just need to adjust your calculations and you are done :-)
An easier solution would be:
Instead of saving the elapsed seconds in your activity, save the time that the timer started (e.g. startTime)
Then, in your handler's runnable, get the current time and subtract the start time to find the elapsed time.
Pseudocode:
long startTimeNanos
public void runTimer() {
startTime = new Date()
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
long currentTime = System.nanoTime()
long elapsedNanos = currentTime - startTimeNanos
// calculate seconds and millis
// and set the textview text
handler.postDelayed(this, 1000);
}
});
}
This way, you can change the time that the handler fires and it won't affect anything else.

Android Chronometer counting backward

I'm new to Android development and currently trying to implement a very simple countdown timer, which shall keep on counting after reaching 00:00, but having the text color in red when below 00:00.
I have two problems:
1) It starts counting from one second less than what I set (in the example it starts at 00:09 instead of at 00:10).
2) After it reaches 00:00, on the next tick it turns the text red but keeps the counter on 00:00 (this latter part is not intended), then continue counting as -00:01, -00:02, etc. So it counts twice on 00:00, once in white, once in red. Any ideas why this occurs? Here's my code:
public class myTimerActivity extends Activity {
Chronometer mainTimer;
long mStartValue = 10; // Countdown value
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the user interface for this Activity
setContentView(R.layout.activity_mytimer);
// Initialize Chronometer object
mainTimer = (Chronometer) findViewById(R.id.chronometer);
mainTimer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
if (SystemClock.elapsedRealtime()>=chronometer.getBase()) {
chronometer.setTextColor(Color.parseColor("#FF0000"));
};
}
});
mainTimer.setFormat("%s");
mainTimer.setBase(SystemClock.elapsedRealtime()+mStartValue*1000);
mainTimer.start();
}
...
}
UPDATE:
Here's another implementation, as suggested by Roger:
public class myTimerActivity extends Activity {
long mStartValue = 10; // Countdown value
private TextView txtCounter;
private static final String FORMAT_COUNTER = "%02d:%02d:%02d";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the user interface for this Activity
setContentView(R.layout.activity_mytimer);
txtCounter = (TextView)findViewById(R.id.mTextField);
new CountDownTimer(mStartValue*1000, 1000) {
public void onTick(long millisUntilFinished) {
txtCounter.setText("" + String.format(FORMAT_COUNTER,
TimeUnit.MILLISECONDS.toHours(millisUntilFinished), // HOURS PASSED
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisUntilFinished)), // MINUTES PASSED (over the hours)
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)) // SECONDS PASSED (over the minutes)
));
}
public void onFinish() {
txtCounter.setTextColor(Color.parseColor("#FF0000"));
}
}.start();
}
...
}

Android - Make a dynamic counter using setText()

I am making a statistical counter that counts upto a certain number (say 60) and the user should see each and every number as it increments on the screen.
TextView display1;
public int stat1 = 60;
public void doSomething(View v){
display1 = (TextView)findViewById(R.id.stat);
for(int i=0;i<=stat1;i++){
String temp = (String.valueOf(i));
for(long j=0;j<1000000;j++);
Log.d("PATO","Value - "+i);
display1.setText(temp);
display1.invalidate();
}
}
However, this code only displays the final number i.e. 60 on the screen even though I can see the increments on the debug screen.
Please find the below solution
protected static void startTimer() {
isTimerRunning = true;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
elapsedTime += 1; //increase every sec
mHandler.obtainMessage(1).sendToTarget();
}
}, 0, 1000);
};
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); //this is the textview
}
}
Above code must work...
Note:mHandler must be created in your main thread.
As your counter is fast . so display1.setText() is overlapping the value, so you cannot see the previous value, so you can do this :
for(int i=0;i<=stat1;i++){
String temp = (String.valueOf(i));
Log.d("Value",temp);
Thread.sleep(1000);
for(long j=0;j<1000000;j++);
Log.d("PATO","Value - "+i);
display1.setText(temp);
display1.invalidate();
}
}

How to make Dynamic change of TextVIew and UI in general?

Good afternoon everyone
So, I'm trying to dynamically change textview's properties.
basically, I defined a Duration. and I want to my handler/runnable to append text to a textView until I reach the duration.
public class Dynamic_testActivity extends Activity
{
public Context context = null;
public TextView view = null;
public Handler mHandler = null;
public long startTime = 0L;
public final int duration_millis = 10000;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = getApplicationContext();
view = (TextView) findViewById(R.id.textView1);
view.append("\n");
mHandler = new Handler();
}
#Override
protected void onStart() {
super.onStart();
startTime = System.currentTimeMillis();
mHandler.post(new Runnable() {
#Override
public void run() {
view.append("Hell_yeah_!\n");
// 10 character lenght
}
});
}
}
So yes, it append the text once, because the run do so.
But how could I make some kind of loop, without blocking the UI Thread, and append text until the end of the duration.
That was the first step ...
The second part now ... In fact, I Want to change the color of the text.
using
Spannable WordtoSpan = new SpannableString(view.getText());
WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 0, view.getText().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
I want to the color changing to be dynamic for the duration ... like a karaoke ...
So, is it possible to make that in the runnable without having the UI Thread blocked until the end of the duration ? and How ?
If anyone could explain the complet process ? or post some source code
Solved.
Here is a basic example...
There is still a little trouble ... at the very beginning of the application, the whole textview is yellow, and after a second, it updates the display as it should be .
If any one knows why, advices are welcome =)
Note : there's only two simple Textview in the layout... Duration is in milliseconds... and there is 10 character in the dynamic textview to fit the duration ... So basically, one char = one second ...
public class Dynamic_testActivity extends Activity
{
public Context context = null;
public TextView view = null;
public TextView view2 = null;
public Handler handler = null;
public long start_time, current_time, elapsed_time = 0L;
public final int duration = 10000;
public int end = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = getApplicationContext();
view = (TextView) findViewById(R.id.textView1);
view2 = (TextView) findViewById(R.id.textView2);
handler = new Handler();
}
#Override
protected void onStart() {
super.onStart();
start_time = Long.valueOf( System.currentTimeMillis() );
current_time = start_time;
handler.postDelayed(new Runnable() {
#Override
public void run() {
current_time = Long.valueOf( System.currentTimeMillis() );
elapsed_time = Long.valueOf(current_time) - Long.valueOf(start_time);
if ( elapsed_time >= duration + 30 ) {
Toast.makeText(context, "Done", Toast.LENGTH_LONG).show();
//finish();
} else {
end = (int) (elapsed_time / 1000);
Spannable WordtoSpan = new SpannableString(view.getText());
WordtoSpan.setSpan(new ForegroundColorSpan(Color.YELLOW), 0, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
view.setText(WordtoSpan);
view2.setText("time : " + elapsed_time);
handler.postDelayed(this, 10);
}
}
}, 10);
}
}
In your run() methond, you can call mHandler.post(this) (or use postDelayed to delay it)
There is property change animation in API level 14, but if you are targetting a lower version, use postDelayed repetively to change progressively the color of the text.

Timer in Android not updating

I have a timer in android to countdown to a future date, but it is not refreshing. Any help appreciated. my code is posted below:
public class Activity1 extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView t = (TextView)findViewById(R.id.countdown);
t.setText(timeDif());
I believe that t.setText just needs to be constantly updated, but am unsure of how to do that.
}
public String timeDif()
{
GregorianCalendar then = new GregorianCalendar(2012, 07, 21, 6, 0, 0);
Calendar now = Calendar.getInstance();
long arriveMilli = then.getTimeInMillis();
long nowMilli = now.getTimeInMillis();
long diff = arriveMilli - nowMilli;
int seconds = (int) (diff / 1000);
int minutes = seconds / 60;
seconds %= 60;
int hours = minutes / 60;
minutes %= 60;
int days = hours / 24;
hours %= 24;
String time = days + ":" +zero(hours)+":"+zero(minutes)+":"+zero(seconds);
return time;
}
private int zero(int hours) {
// TODO Auto-generated method stub
return 0;
}
}
The textbox wont update unless you do it in its own thread. The Timer runs on a different thread than the UI. Here is how I did it.
myTimer = new Timer();
myTimerTask = new TimerTask() {
#Override
public void run() {
TimerMethod();
}
};
myTimer.schedule(myTimerTask, 0, 100);
private void TimerMethod()
{
//This method is called directly by the timer
//and runs in the same thread as the timer.
//We call the method that will work with the UI
//through the runOnUiThread method.
if (isPaused != true) {
this.tmrMilliSeconds--;
this.runOnUiThread(Timer_Tick);
}
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
//This method runs in the same thread as the UI.
if (tmrSeconds > 0) {
if (tmrMilliSeconds <= 0) {
tmrSeconds--;
tmrMilliSeconds = 9;
}
} else {
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(1000);
myTimer.cancel();
tmrSeconds = setTime;
tmrMilliSeconds = 0;
isPaused = true;
}
//Do something to the UI thread here
timerText.setText(String.format("%03d.%d", tmrSeconds, tmrMilliSeconds));
}
};
That is part of the code for a count down clock I made for an ap. It demonstrates how to have one thread run (The public void run()) part, and then another part that runs on the UI thread. Hope that helps.
You shouldn't be doing this with a timer. A timer uses a thread and you don't need one (and it complicates things unnecessarily). You need to use a Runable and Handler's postDelayed method to do it. It is easier and lighter weight.
Handler mHandler = new Handler();
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
//update here
mHandler.postDelayed(mUpdateTimeTask, 100);
}
};
private void startTimer()
{
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
}

Categories

Resources