All the same timers. Stop and Start button.
When loading for the first time, everything is fine, the timers are ticking, after turning the screen and scrolling, the values of the elements change places or disappear.
I'm not sure about the correctness of actions, but in order to display a timer account, I pass the ViewHolder object to its model by pressing the Start button.
Model code snippet:
private String name; private Boolean isStart=false; private Long elapsedTime=0L,seconds=0L,hours=0L,minutes=0L,lastPause=0L,updateTime=0L,startTime=0L,days=0L; private Runnable updateTimeThread=new Runnable() { @Override public void run() { if(isStart && startTime!=0) { updateTime = ((System.currentTimeMillis() - startTime) + lastPause); seconds = updateTime / 1000; minutes = seconds / 60; hours = minutes / 60; seconds = seconds % 60; minutes = minutes % 60; hours = hours % 24; holder.days.setText(String.format("%04d", days)); holder.hours.setText(String.format("%02d", hours)); holder.minutes.setText(String.format("%02d", minutes)); holder.seconds.setText(String.format("%02d", seconds)); Log.d("myTag",name+" "+seconds); MainActivity.handler.post(this); } } }; MyAdapter.ViewHolder holder; public MyAdapter.ViewHolder getHolder() { return holder; } public void setHolder(MyAdapter.ViewHolder holder) { this.holder = holder; } public Runnable getRunnable() { return updateTimeThread; }
Adapter code snippet:
public View getView(final int position, final View convertView, ViewGroup parent) { View row = convertView; final Tracker tracker = trackerList.get(position); final Runnable updateTimeThread=tracker.getRunnable(); View.OnClickListener onClickListener; ViewHolder holder; if(row == null){ holder = new ViewHolder(); LayoutInflater inflater = ((Activity)context).getLayoutInflater(); row = inflater.inflate(R.layout.row,parent,false); holder.name = (TextView)row.findViewById(R.id.tvName); holder.days = (TextView)row.findViewById(R.id.tvDays); holder.hours = (TextView)row.findViewById(R.id.tvHours); holder.minutes = (TextView)row.findViewById(R.id.tvMinutes); holder.seconds = (TextView)row.findViewById(R.id.tvSeconds); holder.start = (Button)row.findViewById(R.id.btStart); holder.stop = (Button)row.findViewById(R.id.btStop); row.setTag(holder); }else { holder = (ViewHolder) row.getTag(); } holder.start.setEnabled(true); holder.stop.setEnabled(false); holder.name.setText(tracker.getName()); final ViewHolder finalHolder = holder; if(tracker.getIsStart()){ holder.start.setEnabled(false); holder.stop.setEnabled(true); } onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btStart: tracker.setStartTime(System.currentTimeMillis()); tracker.setIsStart(true); tracker.setHolder(finalHolder); MainActivity.handler.post(updateTimeThread); finalHolder.start.setEnabled(false); finalHolder.stop.setEnabled(true); break; case R.id.btStop: tracker.setLastPause(tracker.getUpdateTime()); MainActivity.handler.removeCallbacks(updateTimeThread); finalHolder.stop.setEnabled(false); finalHolder.start.setEnabled(true); tracker.setIsStart(false); break; } } }; holder.start.setOnClickListener(onClickListener); holder.stop.setOnClickListener(onClickListener); return row; } static class ViewHolder{ TextView name,days,hours,minutes,seconds; Button start,stop; }
UPDATE The problem was solved for the ArrayAdapter adapter by adding methods, the elements are no longer mixed up and everything works well, I inserted these methods into the SimpleCursorAdapter (in conjunction with LoaderCallback), which can be said to be a twin ArrayAdapter, but it did not work there, and the elements are no longer mixed, but they disappear when scrolling. So close (
@Override public int getViewTypeCount() { if(getCount()==0) return super.getViewTypeCount(); else return getCount(); } @Override public int getItemViewType(int position) { return position; }