Перемешиваются view при скроллинге в listview
Все те же таймеры. Кнопка Стоп и Старт.
При загрузке в первый раз, все нормально, таймеры тикают, после поворота экрана и скроллинга значения элементов меняются местами или пропадают.
Я не уверен на счет правильности действий, но что бы отображать счет таймера, я передаю в его модель объект ViewHolder'a по нажатию на кнопку Старт.
Фрагмент кода модели:
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;
}
Фрагмент кода адаптера:
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 Проблема решилась для адаптера ArrayAdapter добавлением методов, элементы больше не перемешиваются и все работает хорошо, я вставил эти методы в SimpleCursorAdapter(в связке с LoaderCallback), который можно сказать брат близнец ArrayAdapter, но там это не работало, да элементы больше не перемешиваются, но они пропадают при прокрутке. So close(
@Override
public int getViewTypeCount() {
if(getCount()==0)
return super.getViewTypeCount();
else
return getCount();
}
@Override
public int getItemViewType(int position) {
return position;
}
Источник: Stack Overflow на русском