@dandewine

Как реализовать сохранения таймеров при повороте экрана?

При повороте экрана происходит вот это:
RmAtW.jpgjyX8i.jpg
После поворота экрана первый элемент в списке имеет лже-прошедшее время.Вот эта ошибочная инициализация происходит в кастомном адаптере, когда вызывается метод 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;
    }
}
  • Вопрос задан
  • 782 просмотра
Пригласить эксперта
Ответы на вопрос 3
GavriKos
@GavriKos
1) У вас реально brainfuck используется?
2) Нет уж будьте добры весь вопрос сюда писать.
Ответ написан
aratj
@aratj
программер.
а где вы восстанавливаете состояние, что то не вижу.
Ответ написан
atetc
@atetc
Админ Android dev-s чата: https://goo.gl/8JKF1f
при создании новой Activity вызывается метод
onCreate(Bundle savedInstanceState)

Вам нужно из savedInstanceState запросить сохраненные данные:
if (savedInstanceState != null) {
         int elapsed = savedInstanceState.getInt(KEY);
}


Или у вас в другом проблема?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы