При повороте экрана происходит вот это:
После поворота экрана первый элемент в списке имеет лже-прошедшее время.Вот эта ошибочная инициализация происходит в кастомном адаптере, когда вызывается метод setBase() для того хронометра, который действительно отсчитал время. То есть когда position = 2(отсчитал 15с) и проходит проверка и затем вызов метода setBase(), мы попадаем в onTick с postion 0, и ставим ему прошедшее время. Получаем:
1 - 00:15
2 - 00:15
3 - 00:00
4 - 00:10
Потом тоже самое для последнего, поставили базу --> зашли в onTick записали первой позиции - 10 секунд. Получаем красоту:
1 - 00:10
2 - 00:15
3 - 00:00
4 - 00:10
Последняя запись с лога это событие попадание в onTick и вывод прошедшего времени с позицией элемента.
Вот код, я разместил комментарии где все происходит.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d("myTag", "onSaveInstanceState--------------------------------");
for (int i = 0; i <elapsed.size() ; i++) {
if(elapsed.get(i)>1000) {//здесь проверяю, если прошло больше 1с, вставлять нужный елемент списка данные
outState.putLong("elapsedTime " + i, elapsed.get(i));
outState.putLong("lastPause " + i, lastPauseList.get(i));
outState.putLong("position " + i, positionnList.get(i));
outState.putBoolean("ifStart " + i, ifStartlist.get(i));
outState.putLong("base " + i, basesList.get(i));
Log.d("myTag", "elapsedTime = " + getTime(outState.getLong("elapsedTime " + i)));
Log.d("myTag", "lastPause = " + getTime(outState.getLong("lastPause " + i)));
Log.d("myTag", "position = " + outState.getLong("position " + i));
Log.d("myTag", "start = " + outState.getBoolean("ifStart " + i));
Log.d("myTag", "bases = " + getTime(outState.getLong("base " + i)));
Log.d("myTag", "End of SavedInstance --------------------------------------------");
}
}
public class MyAdapter extends SimpleCursorAdapter{
Context context;
int resorceID;
ContentValues cv;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public MyAdapter(Context context,int resourceID,Cursor c,String[] from,int[]to,int flags,List<Tracker> list){
super(context,resourceID,c,from,to,flags);
this.context=context;
this.resorceID=resourceID;
trackersList=list;
elapsed=new ArrayList<Long>(trackersList.size());
lastPauseList = new ArrayList<Long>(trackersList.size());
positionnList = new ArrayList<Integer>(trackersList.size());
ifStartlist = new ArrayList<Boolean>(trackersList.size());
basesList = new ArrayList<Long>(trackersList.size());
for (int i = 0; i < trackersList.size(); i++) {
elapsed.add((long)0);
lastPauseList.add((long)0);
positionnList.add(0);
ifStartlist.add(false);
basesList.add((long)0);
}
tested=elapsed;
cv =new ContentValues();
}
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
TrackHolder holder=null;
View row = convertView;
long bundleLastPause,bundleBase,bundleElapsed;
boolean bundleifStart;
final Tracker tracker = trackersList.get(position);
final long[] lastPause = new long[1];
positionnList.set(position,position);
if(row==null){
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(resorceID,parent,false);
holder = new TrackHolder();
holder.name = (TextView)row.findViewById(R.id.row_name);
holder.chronometer = (Chronometer)row.findViewById(R.id.row_chronometer);
holder.start = (Button)row.findViewById(R.id.btStart);
holder.stop = (Button)row.findViewById(R.id.btStop);
row.setTag(holder);
}else{
holder = (TrackHolder)row.getTag();
}
if(!trackersList.isEmpty()) {
if(bundle!=null){
//инициализация сохраненных значений
bundleBase = bundle.getLong("base " + position);
bundleLastPause = bundle.getLong("lastPause " + position);
bundleElapsed = bundle.getLong("elapsedTime " + position);
bundleifStart = bundle.getBoolean("ifStart " + position);
lastPause[0]=bundleLastPause;
//инициализация список из которых будут сохраняться значения
elapsed.set(position,bundleElapsed);
basesList.set(position,bundleBase);
lastPauseList.set(position,lastPause[0]);
ifStartlist.set(position,bundleifStart);
holder.name.setText(tracker.getName());
if(bundleifStart){//проверка если хронометр был запущен
holder.chronometer.setBase(bundleBase);
holder.start.setEnabled(false);
holder.stop.setEnabled(true);
holder.chronometer.start();
}
if(!bundleifStart && bundleBase>1000 && bundleElapsed>1000){//проверка если был остановлен и прошло больше 1с и наличие базы
holder.chronometer.setBase(bundleBase+(SystemClock.elapsedRealtime()-bundleBase+lastPause[0]));
//после методе выше, position=0 попадает в onTick(при текущей позиции) и заносит в список прошедшего времени время, хотя хронометр
//по этой позиции не был активирован
holder.chronometer.stop();
holder.start.setEnabled(true);
holder.stop.setEnabled(false);
}
}else{//если программа запущена первый раз
holder.name.setText(tracker.getName());
holder.start.setEnabled(true);
holder.stop.setEnabled(false);
}
final TrackHolder finalHolder = holder;
holder.start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finalHolder.chronometer.setBase(SystemClock.elapsedRealtime() +lastPause[0]);
finalHolder.chronometer.start();
finalHolder.stop.setEnabled(true);
finalHolder.start.setEnabled(false);
basesList.set(position, finalHolder.chronometer.getBase());//при нажатии Стар в список баз заноситься база данного хронометра
ifStartlist.set(position,true);//заносится в список статус хронометра
}
});
holder.stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
lastPause[0] = finalHolder.chronometer.getBase()-SystemClock.elapsedRealtime();
finalHolder.chronometer.stop();
finalHolder.start.setEnabled(true);
finalHolder.stop.setEnabled(false);
ifStartlist.set(position, false);//заносится в список статус хронометра
lastPauseList.set(position, lastPause[0]);//заноситься в список время когда была нажата Стоп
elapsed.set(position,SystemClock.elapsedRealtime()-finalHolder.chronometer.getBase());
}
});
holder.chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
if(finalHolder.stop.isEnabled()) {//если кнопки Стоп == true
elapsed.set(position, SystemClock.elapsedRealtime() - finalHolder.chronometer.getBase());
//заносим в список прошедшее время(сюда при любой позиции входит position=0, и в список ему вносится прошедшее время
Log.d("myTag", "elapsedTime = " + getTime(elapsed.get(position)) + " position " + position);
}
}
});
}
return row;
}
String getTime(long time){
int hours = (int)(time/3600000);
int minutes = (int)(time -hours*3600000)/60000;
int seconds = (int)(time-hours*3600000-minutes*60000)/1000;
return ""+hours+":"+minutes+":"+seconds;
}
class TrackHolder{
TextView name;
Chronometer chronometer;
Button start,stop;
}
}