I have a Custom ListView in my application, containing an ImageView and 3-5 TextViews.
1 of the TextViews shows the time gap between the current time
You can also create custom TextView
which updates it self every second or minute or hour. This can be done easily by creating class which extends TextView
and add Handler inside that class. Benefits are that you don't have to update your whole ListView, TextView will update itself automatically.
Example:
public class TextViewTimeCounter extends TextView {
private long mStartTime = 0;
private long mTimeNow = 0;
private int mDelay = 0;
private String mPart1 = "";
private String mPart2 = "";
private Handler mHandler;
public TextViewTimeCounter(Context context) {
super(context, null, 0);
}
public TextViewTimeCounter(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TextViewTimeCounter(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void startTimer(long delay, String part1, String part2){
mStartTime = System.currentTimeMillis();
mTimeNow = System.currentTimeMillis();
mDelay = delay;
mHandler = new Handler();
mHandler.postDelayed(r, delay);
convertDatesToMinutes(mStartTime, mTimeNow);
}
public void stopTimer(){
if(mHandler != null){
mHandler = null;
mStartTime = 0;
mTimeNow = 0;
}
}
public boolean isTimerRunning(){
return mHandler == null? false : true;
}
Runnable r = new Runnable() {
@Override
public void run(){
mTimeNow += mDelay;
convertDatesToMinutes(mStartTime, mTimeNow);
if(mHandler != null){
mHandler.postDelayed(r, mDelay);
}
}
};
public void convertDatesToMinutes(long start, long end){
long secs = (end - start);
long minute = (secs / (1000 * 60)) % 60;
long hour = (secs / (1000 * 60 * 60)) % 24;
String time = String.format(Locale.getDefault(), "%2d hours %2d minutes", hour, minute);
setText(mPart1 + time + mPart2);
}
Usage:
TextViewTimeCounter timer = (TextViewTimeCounter)convertView.findViewById(R.id.start_logging_time_text);
timer.startTimer(10000, "Posted ", " ago");
Output will look like this:
Posted 1 hours 5 minutes ago
If you want to display seconds also, change convertDatesToMinutes(long start, long end)
method to this:
public void convertDatesToMinutes(long start, long end){
long secs = (end - start);
long second = (secs / 1000) % 60;
long minute = (secs / (1000 * 60)) % 60;
long hour = (secs / (1000 * 60 * 60)) % 24;
String time = String.format(Locale.getDefault(), "%2d hours %2d minutes %2d seconds", hour, minute, second);
setText(mPart1 + time + mPart2);
}
Use the built in TimerTask
http://developer.android.com/reference/java/util/TimerTask.html
This is a solid way of doing things.
Use a Handler
and its postDelayed
method to invalidate the list's adapter as follows:
final Handler handler = new Handler()
handler.postDelayed( new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
handler.postDelayed( this, 60 * 1000 );
}
}, 60 * 1000 );
You must only update UI in the main (UI) thread.
By creating the handler in the main thread, you ensure that everything you post to the handler is run in the main thread also.
If you want repeat an action in the main thread in fractions of time you should use "schedule" method of the Time.class
mHandler = new Handler();
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
// run main thread code
}
});
}
}, DELAY_TIME, PERIOD_TIME);