D
D
dandewine2015-04-11 14:53:33
Java
dandewine, 2015-04-11 14:53:33

How to implement saving timers when the screen is rotated?

When the screen is rotated, this is what happens:
RmAtW.jpgjyX8i.jpg
After the screen is rotated, the first item in the list has a false elapsed time. This is the misinitialization that happens in the custom adapter when the setBase() method is called on the chronometer that actually counted the time. That is, when position = 2 (counted 15s) and the check passes and then the call to the setBase () method, we get into onTick with postion 0, and set it to the elapsed time. We get:
1 - 00:15
2 - 00:15
3 - 00:00
4 - 00:10
Then the same for the last one, put the base --> went to onTick and recorded the first position - 10 seconds. Getting beauty:
1 - 00:10
2 - 00:15
3 - 00:00
4 - 00:10
The last entry from the log is the onTick hit event and the output of the elapsed time with the position of the element.
Here is the code, I posted comments where everything happens.

@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;
    }
}

Answer the question

In order to leave comments, you need to log in

3 answer(s)
G
GavriKos, 2015-04-11
@GavriKos

1) Do you really use brainfuck?
2) No, please write the whole question here.

M
Marat S, 2015-04-13
@aratj

and where you restore the state, I don’t see something.

R
Rustem Saitkulov, 2015-04-17
@atetc

when creating a new Activity, the method is called
. You need to request the saved data from savedInstanceState:

if (savedInstanceState != null) {
         int elapsed = savedInstanceState.getInt(KEY);
}

Or do you have a different problem?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question