【问题标题】:Android Chronometer - Save timeAndroid Chronometer - 节省时间
【发布时间】:2015-08-18 17:49:28
【问题描述】:

我在我的 Android 应用中使用 Chronometer。再次按下开始按钮后,我可以启动、停止并继续计数:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_projektbeschreibung, container, false);



    if (savedInstanceState != null){
        stoppedmillis = savedInstanceState.getLong(STATE_TIME);
        hh = savedInstanceState.getString(STATE_HH);
        mm = savedInstanceState.getString(STATE_MM);
        ss = savedInstanceState.getString(STATE_SS);

    }



    mChronometer = (Chronometer) rootView.findViewById(R.id.chronometer2);
    mChronometer.setText(hh + ":" + mm + ":" + ss);
    mChronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
        @Override
        public void onChronometerTick(Chronometer cArg) {
            long time = SystemClock.elapsedRealtime() - cArg.getBase() ;
            int h = (int) (time / 3600000);
            int m = (int) (time - h * 3600000) / 60000;
            int s = (int) (time - h * 3600000 - m * 60000) / 1000;
            hh = h < 10 ? "0" + h : h + "";
            mm = m < 10 ? "0" + m : m + "";
            ss = s < 10 ? "0" + s : s + "";
            cArg.setText(hh + ":" + mm + ":" + ss);

        }
    });


    ((Button) rootView.findViewById(R.id.startbutton)).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //if first start
            if(stoppedmillis == 0) {
                mChronometer.setBase(SystemClock.elapsedRealtime());


            } else {//Point A
                long pausetime = (SystemClock.elapsedRealtime() - stoppedmillis);
                mChronometer.setBase(mChronometer.getBase() + pausetime);
            }
            mChronometer.start();

        }
    });

    ((Button) rootView.findViewById(R.id.stopbutton)).setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View view) {
        mChronometer.stop();
        stoppedmillis = SystemClock.elapsedRealtime();
        }
    });

屏幕旋转后(因此 Activity 重新启动),计时器再次从 00:00:00 点开始计数。我的第一次尝试是使用onSaveInstanceState 方法保存stoppedmillis,如下所示:

 public void onSaveInstanceState(Bundle savedInstanceState){
    savedInstanceState.putLong(STATE_TIME, stoppedmillis);
    savedInstanceState.putString(STATE_HH, hh);
    savedInstanceState.putString(STATE_MM, mm);
    savedInstanceState.putString(STATE_SS,ss);

    super.onSaveInstanceState(savedInstanceState);
}

现在,我可以在重新启动后获取stoppedmillis 的值,但我不知道如何在stoppedmillis 的帮助下为 Chronometer 设置 Base。在代码中的 A 点,您可以看到它如何通过按钮停止 Chronometer 工作,但是这部分代码在屏幕旋转后不起作用。

【问题讨论】:

  • onCreate 方法的一部分未显示。更新您的帖子。

标签: android screen-rotation chronometer


【解决方案1】:

我知道这是旧的。虽然,我使用计时器创建了一个简单的应用程序并完成了以下操作,并且它一直在屏幕旋转中计数。这与安德鲁的原始答案是一致的。这是我的概述:

Chronometer mChronometer; // this is a global variable

@Override
protected void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     mChronometer = (Chronometer)findViewById(R.id.chronometer);


    if(savedInstanceState != null){

       mChronometer.setBase(savedInstanceState.getLong("ChronoTime"));
       mChronometer.start();
          }

    }

现在设置 onSaveInstanceState:

  @Override
  public void onSaveInstanceState (Bundle savedInstanceState){
     super.onSaveInstanceState(savedInstanceState);

     savedInstanceState.putLong("ChronoTime", mChronometer.getBase());
   }

【讨论】:

    【解决方案2】:

    快速解决方案,使用此类: https://github.com/ahmedrizwan/ChronometerPersist/blob/master/chronometerpersist/src/main/java/library/minimize/com/chronometerpersist/ChronometerPersist.java

    ChronometerPersist chronometerPersist = ChronometerPersist.getInstance(chronometer, sharedPreferences);
    
    //Starting the chronometer
    startChronometer();
    //Stoping the chronometer
    stopChronometer();
    //Pausing the chronometer
    pauseChronometer();
    

    我在尝试使用 android chronometer 小部件恢复当前时间时浪费了很多时间。

    【讨论】:

      【解决方案3】:

      这就是我解决保存 Chronometer 状态的方法。

       private static final int TIME_MULTIPLIER = 60;
      

      第 1 步:将时间转换为秒:

      注意:如果您不喜欢我将时间转换为秒的方法,您可以按照自己的方式进行。

       private static int convertTimeToSeconds(Long... time) {
          int seconds = 0;
          if (time.length == 2) {
              seconds += time[0] * TIME_MULTIPLIER + time[1];
          } else if (time.length == 3) {
              seconds += (time[0] * TIME_MULTIPLIER) + (time[1] * TIME_MULTIPLIER) + (time[2]);
          }
          return seconds;
      }
      

      第二步: Chronometer 的设置和启动时间

      注意:我将数据保存在自定义对象中,将该对象与任何数据库/SharedPreference/您的愿望保持一致。

       public static void setAndStartTime(final Chronometer chronometer) {
          long second = 0;
      
         // i have multiple time saved into map. You could save just 1 time and reuse that time.
          for (DailyData data : DailyData.DailyDataHolder.getDailyDataMap().values()) {
              second += data.getDailyTimeSpent();
          }
          chronometer.setBase(SystemClock.elapsedRealtime() - (second * 1000));
          chronometer.start();
      }
      

      第 3 步:节省时间:

      public static void saveTime(String timeText) {
          String[] timeParts = timeText.split("[:]");
          long savedTime = 0;
          if (timeParts.length == 2) {
              savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]));
          } else if (timeParts.length == 3) {
              savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]), Long.parseLong(timeParts[2]));
          }
          DailyData.DailyDataHolder.getDailyData().setDailyTimeSpent(savedTime);
      }
      

      调用保存的方法:

            ChronoHelper.saveTime(chronometer.getText().toString());
      

      完整类:

      public class ChronoHelper {
      
      private static final int TIME_MULTIPLIER = 60;
      
      public static void setAndStartTime(final Chronometer chronometer) {
          long second = 0;
          for (DailyData data : DailyData.DailyDataHolder.getDailyDataMap().values()) {
              second += data.getDailyTimeSpent();
          }
          chronometer.setBase(SystemClock.elapsedRealtime() - (second * 1000));
          chronometer.start();
      }
      
      public static void saveTime(String timeText) {
          String[] timeParts = timeText.split("[:]");
          long savedTime = 0;
          if (timeParts.length == 2) {
              savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]));
          } else if (timeParts.length == 3) {
              savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]), Long.parseLong(timeParts[2]));
          }
          DailyData.DailyDataHolder.getDailyData().setDailyTimeSpent(savedTime);
      }
      
      private static int convertTimeToSeconds(Long... time) {
          int seconds = 0;
          if (time.length == 2) {
              seconds += time[0] * TIME_MULTIPLIER + time[1];
          } else if (time.length == 3) {
              seconds += (time[0] * TIME_MULTIPLIER) + (time[1] * TIME_MULTIPLIER) + (time[2]);
          }
          return seconds;
      }
      
      public static String secondsToTimeText(DailyData dailyData) {
          long savedSeconds = dailyData.getDailyTimeSpent();
          long minutes = savedSeconds / TIME_MULTIPLIER;
          long seconds = savedSeconds % TIME_MULTIPLIER;
          long hours = minutes / TIME_MULTIPLIER;
          return hours + ":" + minutes + ":" + seconds;
         }
      }
      

      【讨论】:

        【解决方案4】:

        将计时器的基准时间保存在onSaveInstanceState 中并将其设置回onRestoreInstanceState,如下所示:

        public void onSaveInstanceState(Bundle savedInstanceState) {
            savedInstanceState.putLong("ChronoTime", mChronometer.getBase());
            super.onSaveInstanceState(savedInstanceState);
        }
        
        public void onRestoreInstanceState(Bundle savedInstanceState){
            if((savedInstanceState !=null) && savedInstanceState.containsKey("ChronoTime"))
                mChronometer.setBase(savedInstanceState.getLong("ChronoTime"));
            super.onRestoreInstanceState(savedInstanceState);
        }
        

        【讨论】:

        • 无法解析 onRestoreInstanceState 方法...我刚刚尝试使用 onSaveInstanceState 保存基准时间并使用 if (savedInstance != null) 恢复它,但无法设置 Chronometer 基准那里。将 Chronometer 底座保存在变量中并使用变量重置底座会导致 Chronometer 计数错误
        • 您可以将onRestoreInstanceState代码放入onCreate。使用保存在onSaveInstanceState 中的值调用chronometer.setBase() 确实有效。即使手机的方向发生变化,它也会继续计数。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-07
        • 2017-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多