This is an interesting question. I've never had to do this before and this answer is just a shot in the dark, but I think you would find some way forward by looking at this answer.
Basically, you need to keep track of which items are visible in your ListView
. Only update the TextView
s in those visible views. To track the visible items you will need to set the ListView
's OnScrollListener
. Use ListView#getFirstVisiblePosition() and ListView#getLastVisiblePosition() to save the first/last positions and then do something with that information. I would try sending them to the adapter and then do what you need to in your adapter's getView() when you are dealing with one of those positions.
Personally I might do something like having my adapter implement some interface that the OnScrollListener
could use to get those positions to the adapter. You may need more than one CountDownTimer
, or you may need to find an alternate method of calculating the time remaining for each event.
UPDATE
The thing with the interfaces would probably suit your purposes better, but here is a proof of concept sample code that will help my point be understood.
This code displays a very simple list in which all even numbered items have a time display that is updated once per second. I make no claims as to the efficiency of this solution, only that it performs the intended task:
MainActivity.java
package com.example.selectivelistitemupdating;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends Activity {
ListView mListView;
MyCountDownTimer mMyCountDownTimer;
@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
mListView = (ListView) findViewById( R.id.listView );
MyAdapter adapter = new MyAdapter( this );
mListView.setAdapter( adapter );
mMyCountDownTimer = new MyCountDownTimer( 1000, 1000, adapter );
}
@Override
protected void onResume() {
super.onResume();
mMyCountDownTimer.start();
}
@Override
protected void onPause() {
mMyCountDownTimer.cancel();
super.onPause();
}
}
MyCountDownTimer.java
package com.example.selectivelistitemupdating;
import android.os.CountDownTimer;
import android.widget.BaseAdapter;
public class MyCountDownTimer extends CountDownTimer {
BaseAdapter mAdapter;
public MyCountDownTimer(long millisInFuture, long countDownInterval, BaseAdapter adapter) {
super( millisInFuture, countDownInterval );
mAdapter = adapter;
}
@Override
public void onFinish() {
mAdapter.notifyDataSetChanged();
this.start();
}
@Override
public void onTick( long millisUntilFinished ) {
// NO OP
}
}
MyAdapter.java
package com.example.selectivelistitemupdating;
import java.text.DateFormat;
import java.util.Calendar;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
private static final int COUNT = 30;
private Context context;
private DateFormat dateFormat;
public MyAdapter(Context context) {
this.context = context;
dateFormat = DateFormat.getTimeInstance();
}
@Override
public int getCount() {
return COUNT;
}
@Override
public String getItem( int position ) {
return "Item " + String.valueOf( position );
}
@Override
public long getItemId( int position ) {
return position;
}
@Override
public View getView( int position, View convertView, ViewGroup parent ) {
if ( convertView == null ) {
convertView = LayoutInflater.from( getContext() ).inflate( android.R.layout.two_line_list_item, parent, false );
}
TextView text1 = (TextView) convertView.findViewById( android.R.id.text1 );
TextView text2 = (TextView) convertView.findViewById( android.R.id.text2 );
text1.setText( getItem( position ) );
text2.setText( getTimeString( position ) );
return convertView;
}
private CharSequence getTimeString( int position ) {
if ( position % 2 == 0 ) {
return dateFormat.format( Calendar.getInstance().getTime() );
}
else {
return null;
}
}
private Context getContext() {
return context;
}
}
activity_main.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />