I am trying to update a textView with timer starting from 00:00:00 every second using Handler. I am also working with custom adapter. So each row has a timer textView,start and stop button. I tried to update the timerTextView in the same row but ended up updating the textView in the last row in the listView.

public class ItemAdapter extends ArrayAdapter<Items> 
{


TextView labelTimer;
int passedSeconds = 0;
Boolean isActivityRunning = false;
Timer timer;
TimerTask timerTask;
Context myContext;
int myLayoutResourceID;
Items[] myData = null;
ItemHolder holder = null;
Integer pos;



public ItemAdapter(Context myContext, int myLayoutResourceID, Items[]     myData) {
super(myContext,myLayoutResourceID,myData);
this.myContext = myContext;
this.myData = myData;
this.myLayoutResourceID = myLayoutResourceID;
}

@Override
public Items getItem(int position)
{
return super.getItem(position);
}




@Override
public View getView(int position, View convertView, ViewGroup parent )
{
View row = convertView;
//ItemHolder holder = null;


if(row == null) {
    LayoutInflater inflater = LayoutInflater.from(myContext);
    row = inflater.inflate(myLayoutResourceID, parent, false);


    holder = new ItemHolder();


    holder.nameView = (TextView) row.findViewById(R.id.nameTextView);
    holder.timerView = (TextView) row.findViewById(R.id.timerTextView);
    holder.imageView = (ImageView) row.findViewById(R.id.imageView);
    holder.startButton = (Button) row.findViewById(R.id.startButton);
    holder.stopButton = (Button) row.findViewById(R.id.stopButton);


    row.setTag(holder);
}

else
{
    holder  = (ItemHolder) row.getTag();
}

Items item  = myData[position];


holder.timerView.setText(item.timer);

final Button srBtn = holder.startButton;
srBtn.setText("START");

//Setup and reuse the same listener each row

Integer rowPosition = position;
pos = position;


holder.startButton.setTag(rowPosition);
holder.timerView.setTag(rowPosition);

final TextView timeV = holder.timerView;
labelTimer = timeV;
labelTimer.setTag(pos);


Log.v("Get tag while creating"+labelTimer.getTag()+"  ","");



//Setting the view to reflect the data we need to display
holder.nameView.setText(item.itemName);



int resid = myContext.getResources().getIdentifier(item.itemImage,"drawable",myContext.getPackageName());
holder.imageView.setImageResource(resid);

holder.startButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (isActivityRunning) {
            //pause running activity
            timer.cancel();
            srBtn.setText("START");
            isActivityRunning = false;
        } else {
            reScheduleTimer();
            srBtn.setText("PAUSE");
            isActivityRunning = true;
        }

    }
});



holder.stopButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        timer.cancel();
        passedSeconds = 0;
        timeV.setText("00 : 00 : 00");
        srBtn.setText("START");
        isActivityRunning = false;
    }
});
return row;
}




public void reScheduleTimer(){

timer = new Timer();
timerTask = new myTimerTask();
timer.schedule(timerTask, 0, 1000);
}


private class myTimerTask extends TimerTask {
@Override
public void run() {
    // TODO Auto-generated method stub
    passedSeconds++;
    updateLabel.sendEmptyMessage(0);
}    
}


private Handler updateLabel = new Handler(){
@Override
public void handleMessage(Message msg) {
    // TODO Auto-generated method stub
    //super.handleMessage(msg);
    int seconds = passedSeconds % 60;
    int minutes = (passedSeconds / 60) % 60;
    int hours = (passedSeconds / 3600);

    Log.v("Get tag while updating = "+labelTimer.getTag()+"  ","");
    labelTimer.setText(String.format("%02d : %02d : %02d", hours,   minutes, seconds));
}
};

private static class ItemHolder {
TextView nameView;
TextView timerView;
ImageView imageView;
Button startButton;
Button stopButton;
}

}

Can someone explain me how to implement this. The answers which are given are below are not providing me solution.

The Link for similar app is : https://play.google.com/store/apps/details?id=com.aloggers.atimeloggerapp&hl=en

2

There are 2 best solutions below

2
On

I see at least few ways. depends on your porouses. 1) Create controller which should be able to access every view created in adapter. holder (in view TAG should have enough information to find codel object for particular view). It also will host one TimerTask. Callback of rimer task should do for each view updating circle. 2) this method used standard listView API with notify data set changed.

1
On

I did this same this using inflating rows in main layout, because it is not work well with adapter.

After binding all views, i used handler.

final Handler handler = new Handler();

private void getList() {
   // arr_savedeal is my ArrayList
    if (arr_savedeal != null) {
        lnr_saved_deal.removeAllViews();

        for (int i = 0; i < 5; i++) {
            // here i am inflating my rows in main layout using linear inflator, same like you did in getView() method of adapter
            rowSavedDeal(arr_savedeal.get(i), i);
        }

        if (arr_savedeal.size() > 0) {
            handler.postDelayed(updateTimerThread, 1000); // where 1000 is 1000ms , means its 1s.
        }
    }
}

private Runnable updateTimerThread = new Runnable() {
    @Override
    public void run() {
        //Do something after 1 second, I am refreshing view here.
        getList();
    }
};

Try this code. Hope this will help you.