1287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinpackage com.android.deskclock.stopwatch; 265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 3cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultasimport android.animation.LayoutTransition; 476a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoroimport android.content.ActivityNotFoundException; 565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport android.content.Context; 6815e2f7431c590086d5bd4eee5d7bf08108c77ebIsaac Katzenelsonimport android.content.Intent; 743474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelsonimport android.content.SharedPreferences; 838d99f23dec1ff7816c8da5ce8a66f3991c67978Isaac Katzenelsonimport android.content.SharedPreferences.OnSharedPreferenceChangeListener; 9319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultasimport android.content.res.Configuration; 1065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport android.os.Bundle; 1164056d415395e8a275910646b4010f55afddec55Isaac Katzenelsonimport android.os.PowerManager; 1264056d415395e8a275910646b4010f55afddec55Isaac Katzenelsonimport android.os.PowerManager.WakeLock; 1343474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelsonimport android.preference.PreferenceManager; 1487bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultasimport android.text.format.DateUtils; 1565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport android.view.LayoutInflater; 1665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport android.view.View; 1765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport android.view.ViewGroup; 18319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultasimport android.view.animation.Animation; 19319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultasimport android.view.animation.TranslateAnimation; 2065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport android.widget.BaseAdapter; 21d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhangimport android.widget.ListPopupWindow; 2265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport android.widget.ListView; 2365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport android.widget.TextView; 2465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 25c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultasimport com.android.deskclock.CircleButtonsLayout; 26287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.CircleTimerView; 27832a20480e1e76d1df846ac20c0eb1fe702a41f8Sam Blitzsteinimport com.android.deskclock.DeskClock; 28287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.DeskClockFragment; 29cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassenimport com.android.deskclock.LogUtils; 30287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.R; 31287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.Utils; 3238d99f23dec1ff7816c8da5ce8a66f3991c67978Isaac Katzenelsonimport com.android.deskclock.timer.CountingTimerView; 33b29cd6c4f734e236a500f41d046105020b73513aIsaac Katzenelson 3465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelsonimport java.util.ArrayList; 3565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 3664056d415395e8a275910646b4010f55afddec55Isaac Katzenelsonpublic class StopwatchFragment extends DeskClockFragment 3764056d415395e8a275910646b4010f55afddec55Isaac Katzenelson implements OnSharedPreferenceChangeListener { 38cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas private static final boolean DEBUG = false; 3964056d415395e8a275910646b4010f55afddec55Isaac Katzenelson 4064056d415395e8a275910646b4010f55afddec55Isaac Katzenelson private static final String TAG = "StopwatchFragment"; 4155f1b9fdaa89d5ecaae0777db979c0c67956d9e1Budi Kusmiantoro private static final int STOPWATCH_REFRESH_INTERVAL_MILLIS = 25; 4255f1b9fdaa89d5ecaae0777db979c0c67956d9e1Budi Kusmiantoro 43287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein int mState = Stopwatches.STOPWATCH_RESET; 4465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 4565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson // Stopwatch views that are accessed by the activity 46660b5227d0f10c95389aad567618d23a130079b3Sam Blitzstein private CircleTimerView mTime; 47fd544b56e462c0e871441bcd48797e022f61d8efIsaac Katzenelson private CountingTimerView mTimeText; 48660b5227d0f10c95389aad567618d23a130079b3Sam Blitzstein private ListView mLapsList; 49d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang private ListPopupWindow mSharePopup; 5064056d415395e8a275910646b4010f55afddec55Isaac Katzenelson private WakeLock mWakeLock; 51319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas private CircleButtonsLayout mCircleLayout; 5265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 53cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // Animation constants and objects 54cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas private LayoutTransition mLayoutTransition; 55cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas private LayoutTransition mCircleLayoutTransition; 56cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas private View mStartSpace; 57cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas private View mEndSpace; 58319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas private boolean mSpacersUsed; 59cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas 6065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson // Used for calculating the time from the start taking into account the pause times 6165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson long mStartTime = 0; 6265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson long mAccumulatedTime = 0; 6365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 6465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson // Lap information 6565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson class Lap { 6665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 6765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson Lap (long time, long total) { 6865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mLapTime = time; 6965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mTotalTime = total; 7065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 7165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public long mLapTime; 7265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public long mTotalTime; 739c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas 74ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas public void updateView() { 759c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas View lapInfo = mLapsList.findViewWithTag(this); 769c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas if (lapInfo != null) { 77ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas mLapsAdapter.setTimeText(lapInfo, this); 789c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas } 799c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas } 8065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 8165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 8265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson // Adapter for the ListView that shows the lap times. 8365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson class LapsListAdapter extends BaseAdapter { 8465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 8565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson ArrayList<Lap> mLaps = new ArrayList<Lap>(); 8665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson private final LayoutInflater mInflater; 8787bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas private final String[] mFormats; 8887bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas private final String[] mLapFormatSet; 8987bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas // Size of this array must match the size of formats 9087bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas private final long[] mThresholds = { 9187bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas 10 * DateUtils.MINUTE_IN_MILLIS, // < 10 minutes 9287bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas DateUtils.HOUR_IN_MILLIS, // < 1 hour 9387bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas 10 * DateUtils.HOUR_IN_MILLIS, // < 10 hours 9487bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas 100 * DateUtils.HOUR_IN_MILLIS, // < 100 hours 9587bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas 1000 * DateUtils.HOUR_IN_MILLIS // < 1000 hours 9687bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas }; 9787bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas private int mLapIndex = 0; 9887bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas private int mTotalIndex = 0; 9987bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas private String mLapFormat; 10065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 10165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public LapsListAdapter(Context context) { 1027b508cb8b3f621b6ea35ecb61773359093a61b81Isaac Katzenelson mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 10387bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mFormats = context.getResources().getStringArray(R.array.stopwatch_format_set); 10487bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mLapFormatSet = context.getResources().getStringArray(R.array.sw_lap_number_set); 10587bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas updateLapFormat(); 10665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 10765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 10865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson @Override 10965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public long getItemId(int position) { 11065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return position; 11165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 11265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 11365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson @Override 11465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public View getView(int position, View convertView, ViewGroup parent) { 11565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (mLaps.size() == 0 || position >= mLaps.size()) { 11665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return null; 11765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 1189c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas Lap lap = getItem(position); 11965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson View lapInfo; 12065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (convertView != null) { 12165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson lapInfo = convertView; 12265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } else { 1239c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas lapInfo = mInflater.inflate(R.layout.lap_view, parent, false); 12465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 1259c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas lapInfo.setTag(lap); 12665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson TextView count = (TextView)lapInfo.findViewById(R.id.lap_number); 127ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas count.setText(String.format(mLapFormat, mLaps.size() - position).toUpperCase()); 128ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas setTimeText(lapInfo, lap); 129ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas 130ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas return lapInfo; 131ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas } 132ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas 133ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas protected void setTimeText(View lapInfo, Lap lap) { 13465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson TextView lapTime = (TextView)lapInfo.findViewById(R.id.lap_time); 1359c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas TextView totalTime = (TextView)lapInfo.findViewById(R.id.lap_total); 1369c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas lapTime.setText(Stopwatches.formatTimeText(lap.mLapTime, mFormats[mLapIndex])); 1379c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas totalTime.setText(Stopwatches.formatTimeText(lap.mTotalTime, mFormats[mTotalIndex])); 13865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 13965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 14065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson @Override 14165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public int getCount() { 14265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return mLaps.size(); 14365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 14465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 14565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson @Override 1469c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas public Lap getItem(int position) { 14765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (mLaps.size() == 0 || position >= mLaps.size()) { 14865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return null; 14965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 15065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return mLaps.get(position); 15165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 15265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 15387bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas private void updateLapFormat() { 15487bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas // Note Stopwatches.MAX_LAPS < 100 15587bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mLapFormat = mLapFormatSet[mLaps.size() < 10 ? 0 : 1]; 15687bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas } 15787bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas 15887bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas private void resetTimeFormats() { 15987bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mLapIndex = mTotalIndex = 0; 16087bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas } 16187bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas 1629c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas /** 1639c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas * A lap is printed into two columns: the total time and the lap time. To make this print 1649c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas * as pretty as possible, multiple formats were created which minimize the width of the 1659c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas * print. As the total or lap time exceed the limit of that format, this code updates 1669c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas * the format used for the total and/or lap times. 1679c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas * 1689c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas * @param lap to measure 1699c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas * @return true if this lap exceeded either threshold and a format was updated. 1709c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas */ 17187bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas public boolean updateTimeFormats(Lap lap) { 17287bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas boolean formatChanged = false; 17387bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas while (mLapIndex + 1 < mThresholds.length && lap.mLapTime >= mThresholds[mLapIndex]) { 17487bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mLapIndex++; 17587bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas formatChanged = true; 17687bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas } 177d48339f270ba72bb8416fd194b4a0d1aeb3bd958rachelzhang while (mTotalIndex + 1 < mThresholds.length && 1782caafe1670be104d4d4781f0b0fab2e9ae2153b7Romain Guy lap.mTotalTime >= mThresholds[mTotalIndex]) { 17987bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mTotalIndex++; 18087bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas formatChanged = true; 18187bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas } 18287bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas return formatChanged; 18387bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas } 18487bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas 18565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public void addLap(Lap l) { 18665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mLaps.add(0, l); 18787bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas // for efficiency caller also calls notifyDataSetChanged() 18865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 18965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 19065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public void clearLaps() { 19165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mLaps.clear(); 19287bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas updateLapFormat(); 19387bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas resetTimeFormats(); 19465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson notifyDataSetChanged(); 19565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 19665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 197c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // Helper function used to get the lap data to be stored in the activity's bundle 19865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public long [] getLapTimes() { 19965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson int size = mLaps.size(); 20065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (size == 0) { 20165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return null; 20265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 20365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson long [] laps = new long[size]; 20465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson for (int i = 0; i < size; i ++) { 205287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein laps[i] = mLaps.get(i).mTotalTime; 20665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 20765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return laps; 20865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 20965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 21065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson // Helper function to restore adapter's data from the activity's bundle 21165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public void setLapTimes(long [] laps) { 21265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (laps == null || laps.length == 0) { 21365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return; 21465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 21565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 21665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson int size = laps.length; 21765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mLaps.clear(); 218c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas for (long lap : laps) { 219c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mLaps.add(new Lap(lap, 0)); 22065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 22165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson long totalTime = 0; 22265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson for (int i = size -1; i >= 0; i --) { 22365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson totalTime += laps[i]; 22465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mLaps.get(i).mTotalTime = totalTime; 22587bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas updateTimeFormats(mLaps.get(i)); 22665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 22787bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas updateLapFormat(); 228c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas showLaps(); 22965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson notifyDataSetChanged(); 23065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 23165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 23265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 23365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson LapsListAdapter mLapsAdapter; 23465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 23565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public StopwatchFragment() { 23665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 23765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 2384261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting private void rightButtonAction() { 2394261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting long time = Utils.getTimeNow(); 2404261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting Context context = getActivity().getApplicationContext(); 2414261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting Intent intent = new Intent(context, StopwatchService.class); 2424261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting intent.putExtra(Stopwatches.MESSAGE_TIME, time); 2434261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting intent.putExtra(Stopwatches.SHOW_NOTIF, false); 2444261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting switch (mState) { 2454261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting case Stopwatches.STOPWATCH_RUNNING: 2464261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting // do stop 2474261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting long curTime = Utils.getTimeNow(); 2484261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting mAccumulatedTime += (curTime - mStartTime); 2494261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting doStop(); 2504261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting intent.setAction(Stopwatches.STOP_STOPWATCH); 2514261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting context.startService(intent); 25264056d415395e8a275910646b4010f55afddec55Isaac Katzenelson releaseWakeLock(); 2534261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting break; 2544261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting case Stopwatches.STOPWATCH_RESET: 2554261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting case Stopwatches.STOPWATCH_STOPPED: 2564261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting // do start 2574261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting doStart(time); 2584261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting intent.setAction(Stopwatches.START_STOPWATCH); 2594261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting context.startService(intent); 26064056d415395e8a275910646b4010f55afddec55Isaac Katzenelson acquireWakeLock(); 2614261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting break; 2624261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting default: 263cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen LogUtils.wtf("Illegal state " + mState 2644261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting + " while pressing the right stopwatch button"); 2654261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting break; 2664261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting } 2674261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting } 2684261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting 26965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson @Override 27065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public View onCreateView(LayoutInflater inflater, ViewGroup container, 27165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson Bundle savedInstanceState) { 27265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson // Inflate the layout for this fragment 273cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas ViewGroup v = (ViewGroup)inflater.inflate(R.layout.stopwatch_fragment, container, false); 274287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 275c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mTime = (CircleTimerView)v.findViewById(R.id.stopwatch_time); 276c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mTimeText = (CountingTimerView)v.findViewById(R.id.stopwatch_time_text); 277c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mLapsList = (ListView)v.findViewById(R.id.laps_list); 278c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mLapsList.setDividerHeight(0); 279c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mLapsAdapter = new LapsListAdapter(getActivity()); 280c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mLapsList.setAdapter(mLapsAdapter); 281c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas 282c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mTimeText.setVirtualButtonEnabled(true); 2834261870a93db4e92bf5c08a9a253c9c5ff80d41cSara Ting 284319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayout = (CircleButtonsLayout)v.findViewById(R.id.stopwatch_circle); 285d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang mCircleLayout.setCircleTimerViewIds(R.id.stopwatch_time, 0 /* stopwatchId */ , 286d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang 0 /* labelId */, 0 /* labeltextId */); 28700cb5981c984bc13aa2f6af510a9dd9a784f2af0Sam Blitzstein 288cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // Animation setup 289319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mLayoutTransition = new LayoutTransition(); 290319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayoutTransition = new LayoutTransition(); 291319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas 292319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas // The CircleButtonsLayout only needs to undertake location changes 293319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayoutTransition.enableTransitionType(LayoutTransition.CHANGING); 294319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayoutTransition.disableTransitionType(LayoutTransition.APPEARING); 295319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayoutTransition.disableTransitionType(LayoutTransition.DISAPPEARING); 296319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_APPEARING); 297319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING); 298319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayoutTransition.setAnimateParentHierarchy(false); 299319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas 300319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas // These spacers assist in keeping the size of CircleButtonsLayout constant 301cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas mStartSpace = v.findViewById(R.id.start_space); 302cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas mEndSpace = v.findViewById(R.id.end_space); 303319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mSpacersUsed = mStartSpace != null || mEndSpace != null; 304319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas // Listener to invoke extra animation within the laps-list 305319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mLayoutTransition.addTransitionListener(new LayoutTransition.TransitionListener() { 306319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas @Override 307319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas public void startTransition(LayoutTransition transition, ViewGroup container, 308319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas View view, int transitionType) { 309319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (view == mLapsList) { 310319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (transitionType == LayoutTransition.DISAPPEARING) { 311cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen if (DEBUG) LogUtils.v("StopwatchFragment.start laps-list disappearing"); 312319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas boolean shiftX = view.getResources().getConfiguration().orientation 313319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas == Configuration.ORIENTATION_LANDSCAPE; 314319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas int first = mLapsList.getFirstVisiblePosition(); 315319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas int last = mLapsList.getLastVisiblePosition(); 316319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas // Ensure index range will not cause a divide by zero 317319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (last < first) { 318319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas last = first; 319319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 320319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas long duration = transition.getDuration(LayoutTransition.DISAPPEARING); 321319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas long offset = duration / (last - first + 1) / 5; 322319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas for (int visibleIndex = first; visibleIndex <= last; visibleIndex++) { 323319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas View lapView = mLapsList.getChildAt(visibleIndex - first); 324319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (lapView != null) { 325319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas float toXValue = shiftX ? 1.0f * (visibleIndex - first + 1) : 0; 326319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas float toYValue = shiftX ? 0 : 4.0f * (visibleIndex - first + 1); 327319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas TranslateAnimation animation = new TranslateAnimation( 328319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas Animation.RELATIVE_TO_SELF, 0, 329319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas Animation.RELATIVE_TO_SELF, toXValue, 330319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas Animation.RELATIVE_TO_SELF, 0, 331319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas Animation.RELATIVE_TO_SELF, toYValue); 332319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas animation.setStartOffset((last - visibleIndex) * offset); 333319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas animation.setDuration(duration); 334319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas lapView.startAnimation(animation); 335319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 336319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 337319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 338319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 339319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 340319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas 341319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas @Override 342319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas public void endTransition(LayoutTransition transition, ViewGroup container, 343319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas View view, int transitionType) { 344319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (transitionType == LayoutTransition.DISAPPEARING) { 345cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen if (DEBUG) LogUtils.v("StopwatchFragment.end laps-list disappearing"); 346319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas int last = mLapsList.getLastVisiblePosition(); 347319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas for (int visibleIndex = mLapsList.getFirstVisiblePosition(); 348319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas visibleIndex <= last; visibleIndex++) { 349319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas View lapView = mLapsList.getChildAt(visibleIndex); 350319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (lapView != null) { 351319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas Animation animation = lapView.getAnimation(); 352319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (animation != null) { 353319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas animation.cancel(); 354319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 355319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 356319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 357319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 358319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 359319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas }); 360cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas 36165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson return v; 36265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 36365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 364cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas /** 365319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas * Make the final display setup. 366319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas * 367319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas * If the fragment is starting with an existing list of laps, shows the laps list and if the 368319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas * spacers around the clock exist, hide them. If there are not laps at the start, hide the laps 369319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas * list and show the clock spacers if they exist. 370cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas */ 371cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas @Override 372cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas public void onStart() { 373cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas super.onStart(); 374319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas 375319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas boolean lapsVisible = mLapsAdapter.getCount() > 0; 376319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas 377319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mLapsList.setVisibility(lapsVisible ? View.VISIBLE : View.GONE); 378319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (mSpacersUsed) { 379319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas int spacersVisibility = lapsVisible ? View.GONE : View.VISIBLE; 380319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (mStartSpace != null) { 381319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mStartSpace.setVisibility(spacersVisibility); 382319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 383319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (mEndSpace != null) { 384319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mEndSpace.setVisibility(spacersVisibility); 385319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 386319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 387319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas ((ViewGroup)getView()).setLayoutTransition(mLayoutTransition); 388319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mCircleLayout.setLayoutTransition(mCircleLayoutTransition); 389cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas } 390cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas 39165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson @Override 39265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public void onResume() { 3937b508cb8b3f621b6ea35ecb61773359093a61b81Isaac Katzenelson SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 394287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein prefs.registerOnSharedPreferenceChangeListener(this); 39543474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson readFromSharedPref(prefs); 39643474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson mTime.readFromSharedPref(prefs, "sw"); 397287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.postInvalidate(); 398287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 3995e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setFabAppearance(); 4005e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setLeftRightButtonAppearance(); 40126fd3d012330e5abf4f6452e811938374004d0d8Sam Blitzstein mTimeText.setTime(mAccumulatedTime, true, true); 402287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (mState == Stopwatches.STOPWATCH_RUNNING) { 40364056d415395e8a275910646b4010f55afddec55Isaac Katzenelson acquireWakeLock(); 40465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson startUpdateThread(); 405287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } else if (mState == Stopwatches.STOPWATCH_STOPPED && mAccumulatedTime != 0) { 40643474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson mTimeText.blinkTimeStr(true); 40765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 40865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson showLaps(); 40964056d415395e8a275910646b4010f55afddec55Isaac Katzenelson ((DeskClock)getActivity()).registerPageChangedListener(this); 4109633b6cffd00506af022cbde5315b707c5b20e84Isaac Katzenelson // View was hidden in onPause, make sure it is visible now. 4119633b6cffd00506af022cbde5315b707c5b20e84Isaac Katzenelson View v = getView(); 4129633b6cffd00506af022cbde5315b707c5b20e84Isaac Katzenelson if (v != null) { 413c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas v.setVisibility(View.VISIBLE); 4149633b6cffd00506af022cbde5315b707c5b20e84Isaac Katzenelson } 41565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson super.onResume(); 41665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 41765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 41865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson @Override 41965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public void onPause() { 420287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (mState == Stopwatches.STOPWATCH_RUNNING) { 42165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson stopUpdateThread(); 42276a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro 42376a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro // This is called because the lock screen was activated, the window stay 42476a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro // active under it and when we unlock the screen, we see the old time for 42576a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro // a fraction of a second. 42676a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro View v = getView(); 42776a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro if (v != null) { 42876a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro v.setVisibility(View.INVISIBLE); 42976a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro } 43065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 43143474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson // The stopwatch must keep running even if the user closes the app so save stopwatch state 43243474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson // in shared prefs 4337b508cb8b3f621b6ea35ecb61773359093a61b81Isaac Katzenelson SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 434287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein prefs.unregisterOnSharedPreferenceChangeListener(this); 43543474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson writeToSharedPref(prefs); 43643474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson mTime.writeToSharedPref(prefs, "sw"); 437dbefec37e0c0a3a8d832e5c34697fa0492e1077cIsaac Katzenelson mTimeText.blinkTimeStr(false); 43864056d415395e8a275910646b4010f55afddec55Isaac Katzenelson ((DeskClock)getActivity()).unregisterPageChangedListener(this); 43964056d415395e8a275910646b4010f55afddec55Isaac Katzenelson releaseWakeLock(); 44065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson super.onPause(); 44165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 44265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 44364056d415395e8a275910646b4010f55afddec55Isaac Katzenelson @Override 44464056d415395e8a275910646b4010f55afddec55Isaac Katzenelson public void onPageChanged(int page) { 44564056d415395e8a275910646b4010f55afddec55Isaac Katzenelson if (page == DeskClock.STOPWATCH_TAB_INDEX && mState == Stopwatches.STOPWATCH_RUNNING) { 44664056d415395e8a275910646b4010f55afddec55Isaac Katzenelson acquireWakeLock(); 44764056d415395e8a275910646b4010f55afddec55Isaac Katzenelson } else { 44864056d415395e8a275910646b4010f55afddec55Isaac Katzenelson releaseWakeLock(); 44964056d415395e8a275910646b4010f55afddec55Isaac Katzenelson } 45064056d415395e8a275910646b4010f55afddec55Isaac Katzenelson } 45164056d415395e8a275910646b4010f55afddec55Isaac Katzenelson 452287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein private void doStop() { 453cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen if (DEBUG) LogUtils.v("StopwatchFragment.doStop"); 454287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein stopUpdateThread(); 455287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.pauseIntervalAnimation(); 45626fd3d012330e5abf4f6452e811938374004d0d8Sam Blitzstein mTimeText.setTime(mAccumulatedTime, true, true); 457287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTimeText.blinkTimeStr(true); 458287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein updateCurrentLap(mAccumulatedTime); 459287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mState = Stopwatches.STOPWATCH_STOPPED; 4605e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setFabAppearance(); 4615e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setLeftRightButtonAppearance(); 462287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 463287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 464287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein private void doStart(long time) { 465cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen if (DEBUG) LogUtils.v("StopwatchFragment.doStart"); 466287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mStartTime = time; 467287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein startUpdateThread(); 468287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTimeText.blinkTimeStr(false); 469287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (mTime.isAnimating()) { 470287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.startIntervalAnimation(); 471287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 472287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mState = Stopwatches.STOPWATCH_RUNNING; 4735e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setFabAppearance(); 4745e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setLeftRightButtonAppearance(); 475287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 476287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 477287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein private void doLap() { 478cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen if (DEBUG) LogUtils.v("StopwatchFragment.doLap"); 479287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein showLaps(); 4805e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setFabAppearance(); 4815e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setLeftRightButtonAppearance(); 482287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 483287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 484287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein private void doReset() { 485cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen if (DEBUG) LogUtils.v("StopwatchFragment.doReset"); 486287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein SharedPreferences prefs = 487287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein PreferenceManager.getDefaultSharedPreferences(getActivity()); 488de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson Utils.clearSwSharedPref(prefs); 489287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.clearSharedPref(prefs, "sw"); 490287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mAccumulatedTime = 0; 491287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mLapsAdapter.clearLaps(); 492287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein showLaps(); 493287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.stopIntervalAnimation(); 494287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.reset(); 49526fd3d012330e5abf4f6452e811938374004d0d8Sam Blitzstein mTimeText.setTime(mAccumulatedTime, true, true); 496287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTimeText.blinkTimeStr(false); 497287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mState = Stopwatches.STOPWATCH_RESET; 4985e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setFabAppearance(); 4995e469aa155baea98f09d5d5e657aa2315a76679drachelzhang setLeftRightButtonAppearance(); 50065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 50165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 50276a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro private void shareResults() { 50376a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro final Context context = getActivity(); 50476a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro final Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND); 50576a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro shareIntent.setType("text/plain"); 50676a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 50776a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro shareIntent.putExtra(Intent.EXTRA_SUBJECT, 50876a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro Stopwatches.getShareTitle(context.getApplicationContext())); 50976a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro shareIntent.putExtra(Intent.EXTRA_TEXT, Stopwatches.buildShareResults( 510287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein getActivity().getApplicationContext(), mTimeText.getTimeString(), 511287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein getLapShareTimes(mLapsAdapter.getLapTimes()))); 51276a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro 51376a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro final Intent launchIntent = Intent.createChooser(shareIntent, 51476a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro context.getString(R.string.sw_share_button)); 51576a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro try { 51676a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro context.startActivity(launchIntent); 51776a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro } catch (ActivityNotFoundException e) { 518cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen LogUtils.e("No compatible receiver is found"); 51976a34b3ddb42e172900ad984ea327d030e805befBudi Kusmiantoro } 520287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 521287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 522287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein /** Turn laps as they would be saved in prefs into format for sharing. **/ 523287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein private long[] getLapShareTimes(long[] input) { 524287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (input == null) { 525287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein return null; 526287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 527287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 528287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein int numLaps = input.length; 529287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein long[] output = new long[numLaps]; 530287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein long prevLapElapsedTime = 0; 531287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein for (int lap_i = numLaps - 1; lap_i >= 0; lap_i--) { 532287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein long lap = input[lap_i]; 533cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen LogUtils.v("lap " + lap_i + ": " + lap); 534287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein output[lap_i] = lap - prevLapElapsedTime; 535287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein prevLapElapsedTime = lap; 536287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 537287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein return output; 538287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 539287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 54065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson private boolean reachedMaxLaps() { 541287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein return mLapsAdapter.getCount() >= Stopwatches.MAX_LAPS; 54265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 54365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 54465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson /*** 545c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas * Handle action when user presses the lap button 5469c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas * @param time - in hundredth of a second 5474ad5b75cd1c5ec94b2122f10f2f02137e1c0e9b2Isaac Katzenelson */ 54865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson private void addLapTime(long time) { 549c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // The total elapsed time 550c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas final long curTime = time - mStartTime + mAccumulatedTime; 55165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson int size = mLapsAdapter.getCount(); 55265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (size == 0) { 553c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // Create and add the first lap 55487bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas Lap firstLap = new Lap(curTime, curTime); 55587bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mLapsAdapter.addLap(firstLap); 556c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // Create the first active lap 55765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mLapsAdapter.addLap(new Lap(0, curTime)); 558c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // Update the interval on the clock and check the lap and total time formatting 559287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.setIntervalTime(curTime); 56087bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mLapsAdapter.updateTimeFormats(firstLap); 56165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } else { 562c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // Finish active lap 563c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas final long lapTime = curTime - mLapsAdapter.getItem(1).mTotalTime; 5649c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas mLapsAdapter.getItem(0).mLapTime = lapTime; 5659c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas mLapsAdapter.getItem(0).mTotalTime = curTime; 566c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // Create a new active lap 567c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas mLapsAdapter.addLap(new Lap(0, curTime)); 568c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // Update marker on clock and check that formatting for the lap number 569287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.setMarkerTime(lapTime); 57087bf27c22cf71bfb89e97eba92d4513148d3d8c8Robyn Coultas mLapsAdapter.updateLapFormat(); 57165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 572c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas // Repaint the laps list 57365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mLapsAdapter.notifyDataSetChanged(); 574c9524f8b8216c7854de4c69c44c9bb63e4097a18Robyn Coultas 57565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson // Start lap animation starting from the second lap 5769c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas mTime.stopIntervalAnimation(); 5779c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas if (!reachedMaxLaps()) { 5789c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas mTime.startIntervalAnimation(); 5799c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas } 58065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 58165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 582287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein private void updateCurrentLap(long totalTime) { 5839c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas // There are either 0, 2 or more Laps in the list See {@link #addLapTime} 58465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (mLapsAdapter.getCount() > 0) { 5859c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas Lap curLap = mLapsAdapter.getItem(0); 5869c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas curLap.mLapTime = totalTime - mLapsAdapter.getItem(1).mTotalTime; 58765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson curLap.mTotalTime = totalTime; 5889c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas // If this lap has caused a change in the format for total and/or lap time, all of 5899c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas // the rows need a fresh print. The simplest way to refresh all of the rows is 5909c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas // calling notifyDataSetChanged. 5919c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas if (mLapsAdapter.updateTimeFormats(curLap)) { 5929c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas mLapsAdapter.notifyDataSetChanged(); 5939c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas } else { 594ab7b489e853a376d4e06d74c5ee42747bb8ffed7Robyn Coultas curLap.updateView(); 5959c483781c2a4bbc2b7ca228ea959f99cc0be149bRobyn Coultas } 59665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 59765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 59865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 599cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas /** 600cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas * Show or hide the laps-list 601cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas */ 60265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson private void showLaps() { 603cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen if (DEBUG) LogUtils.v(String.format("StopwatchFragment.showLaps: count=%d", 604cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas mLapsAdapter.getCount())); 605cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas 606319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas boolean lapsVisible = mLapsAdapter.getCount() > 0; 607319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas 608cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // Layout change animations will start upon the first add/hide view. Temporarily disable 609cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // the layout transition animation for the spacers, make the changes, then re-enable 610cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // the animation for the add/hide laps-list 611319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (mSpacersUsed) { 612319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas int spacersVisibility = lapsVisible ? View.GONE : View.VISIBLE; 613cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas ViewGroup rootView = (ViewGroup) getView(); 614319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (rootView != null) { 615319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas rootView.setLayoutTransition(null); 616319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (mStartSpace != null) { 617319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mStartSpace.setVisibility(spacersVisibility); 618319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 619319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (mEndSpace != null) { 620319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mEndSpace.setVisibility(spacersVisibility); 621319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas } 622319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas rootView.setLayoutTransition(mLayoutTransition); 623cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas } 624cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas } 625cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas 626319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas if (lapsVisible) { 627cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // There are laps - show the laps-list 628cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // No delay for the CircleButtonsLayout changes - start immediately so that the 629cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // circle has shifted before the laps-list starts appearing. 630cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas mCircleLayoutTransition.setStartDelay(LayoutTransition.CHANGING, 0); 631319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas 632319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mLapsList.setVisibility(View.VISIBLE); 63365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } else { 634cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas // There are no laps - hide the laps list 635cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas 636319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas // Delay the CircleButtonsLayout animation until after the laps-list disappears 637cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas long startDelay = mLayoutTransition.getStartDelay(LayoutTransition.DISAPPEARING) + 638cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas mLayoutTransition.getDuration(LayoutTransition.DISAPPEARING); 639cffb4dbf6e1fed0e0c18c2ea5073227c85ca3f9aRobyn Coultas mCircleLayoutTransition.setStartDelay(LayoutTransition.CHANGING, startDelay); 640319265e3e8564f3e71dca8bc752632c9a1708938Robyn Coultas mLapsList.setVisibility(View.GONE); 64165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 64265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 64365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 64465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson private void startUpdateThread() { 64565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mTime.post(mTimeUpdateThread); 64665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 64765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 64865d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson private void stopUpdateThread() { 64965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson mTime.removeCallbacks(mTimeUpdateThread); 65065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 65165d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 65265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson Runnable mTimeUpdateThread = new Runnable() { 65365d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson @Override 65465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson public void run() { 655287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein long curTime = Utils.getTimeNow(); 65665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson long totalTime = mAccumulatedTime + (curTime - mStartTime); 65765d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (mTime != null) { 65826fd3d012330e5abf4f6452e811938374004d0d8Sam Blitzstein mTimeText.setTime(totalTime, true, true); 65965d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 66065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson if (mLapsAdapter.getCount() > 0) { 661287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein updateCurrentLap(totalTime); 66265d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 66355f1b9fdaa89d5ecaae0777db979c0c67956d9e1Budi Kusmiantoro mTime.postDelayed(mTimeUpdateThread, STOPWATCH_REFRESH_INTERVAL_MILLIS); 66465d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson } 66565d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson }; 66665d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson 66743474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson private void writeToSharedPref(SharedPreferences prefs) { 66843474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson SharedPreferences.Editor editor = prefs.edit(); 669287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putLong (Stopwatches.PREF_START_TIME, mStartTime); 670287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putLong (Stopwatches.PREF_ACCUM_TIME, mAccumulatedTime); 671287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putInt (Stopwatches.PREF_STATE, mState); 67243474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson if (mLapsAdapter != null) { 67343474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson long [] laps = mLapsAdapter.getLapTimes(); 67443474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson if (laps != null) { 675287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putInt (Stopwatches.PREF_LAP_NUM, laps.length); 67643474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson for (int i = 0; i < laps.length; i++) { 677287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein String key = Stopwatches.PREF_LAP_TIME + Integer.toString(laps.length - i); 67843474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson editor.putLong (key, laps[i]); 67943474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson } 68043474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson } 68143474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson } 682287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (mState == Stopwatches.STOPWATCH_RUNNING) { 683287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putLong(Stopwatches.NOTIF_CLOCK_BASE, mStartTime-mAccumulatedTime); 684287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putLong(Stopwatches.NOTIF_CLOCK_ELAPSED, -1); 685287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, true); 686287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } else if (mState == Stopwatches.STOPWATCH_STOPPED) { 687287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putLong(Stopwatches.NOTIF_CLOCK_ELAPSED, mAccumulatedTime); 688287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putLong(Stopwatches.NOTIF_CLOCK_BASE, -1); 689287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, false); 690287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } else if (mState == Stopwatches.STOPWATCH_RESET) { 691287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.remove(Stopwatches.NOTIF_CLOCK_BASE); 692287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.remove(Stopwatches.NOTIF_CLOCK_RUNNING); 693287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.remove(Stopwatches.NOTIF_CLOCK_ELAPSED); 694287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 695287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein editor.putBoolean(Stopwatches.PREF_UPDATE_CIRCLE, false); 69643474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson editor.apply(); 69743474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson } 69843474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson 69943474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson private void readFromSharedPref(SharedPreferences prefs) { 700287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mStartTime = prefs.getLong(Stopwatches.PREF_START_TIME, 0); 701287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mAccumulatedTime = prefs.getLong(Stopwatches.PREF_ACCUM_TIME, 0); 702287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mState = prefs.getInt(Stopwatches.PREF_STATE, Stopwatches.STOPWATCH_RESET); 703287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein int numLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, Stopwatches.STOPWATCH_RESET); 70443474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson if (mLapsAdapter != null) { 705287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein long[] oldLaps = mLapsAdapter.getLapTimes(); 706287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (oldLaps == null || oldLaps.length < numLaps) { 707287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein long[] laps = new long[numLaps]; 708287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein long prevLapElapsedTime = 0; 709287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein for (int lap_i = 0; lap_i < numLaps; lap_i++) { 710287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein String key = Stopwatches.PREF_LAP_TIME + Integer.toString(lap_i + 1); 711287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein long lap = prefs.getLong(key, 0); 712287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein laps[numLaps - lap_i - 1] = lap - prevLapElapsedTime; 713287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein prevLapElapsedTime = lap; 714287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 715287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mLapsAdapter.setLapTimes(laps); 716287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 717287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 718287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (prefs.getBoolean(Stopwatches.PREF_UPDATE_CIRCLE, true)) { 719287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (mState == Stopwatches.STOPWATCH_STOPPED) { 720287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein doStop(); 721287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } else if (mState == Stopwatches.STOPWATCH_RUNNING) { 722287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein doStart(mStartTime); 723287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } else if (mState == Stopwatches.STOPWATCH_RESET) { 724287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein doReset(); 72543474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson } 72643474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson } 72743474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson } 72843474e446f4fd103b0f609d1be75c4825adb8b58Isaac Katzenelson 729287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein @Override 730287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 731287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (prefs.equals(PreferenceManager.getDefaultSharedPreferences(getActivity()))) { 732287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (! (key.equals(Stopwatches.PREF_LAP_NUM) || 733287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein key.startsWith(Stopwatches.PREF_LAP_TIME))) { 734287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein readFromSharedPref(prefs); 735287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein if (prefs.getBoolean(Stopwatches.PREF_UPDATE_CIRCLE, true)) { 736287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein mTime.readFromSharedPref(prefs, "sw"); 737287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 738287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 739287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 740287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 74164056d415395e8a275910646b4010f55afddec55Isaac Katzenelson 74264056d415395e8a275910646b4010f55afddec55Isaac Katzenelson // Used to keeps screen on when stopwatch is running. 74364056d415395e8a275910646b4010f55afddec55Isaac Katzenelson 74464056d415395e8a275910646b4010f55afddec55Isaac Katzenelson private void acquireWakeLock() { 74564056d415395e8a275910646b4010f55afddec55Isaac Katzenelson if (mWakeLock == null) { 74664056d415395e8a275910646b4010f55afddec55Isaac Katzenelson final PowerManager pm = 74764056d415395e8a275910646b4010f55afddec55Isaac Katzenelson (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE); 74864056d415395e8a275910646b4010f55afddec55Isaac Katzenelson mWakeLock = pm.newWakeLock( 74964056d415395e8a275910646b4010f55afddec55Isaac Katzenelson PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG); 75064056d415395e8a275910646b4010f55afddec55Isaac Katzenelson mWakeLock.setReferenceCounted(false); 75164056d415395e8a275910646b4010f55afddec55Isaac Katzenelson } 75264056d415395e8a275910646b4010f55afddec55Isaac Katzenelson mWakeLock.acquire(); 75364056d415395e8a275910646b4010f55afddec55Isaac Katzenelson } 75464056d415395e8a275910646b4010f55afddec55Isaac Katzenelson 75564056d415395e8a275910646b4010f55afddec55Isaac Katzenelson private void releaseWakeLock() { 75664056d415395e8a275910646b4010f55afddec55Isaac Katzenelson if (mWakeLock != null && mWakeLock.isHeld()) { 75764056d415395e8a275910646b4010f55afddec55Isaac Katzenelson mWakeLock.release(); 75864056d415395e8a275910646b4010f55afddec55Isaac Katzenelson } 75964056d415395e8a275910646b4010f55afddec55Isaac Katzenelson } 76064056d415395e8a275910646b4010f55afddec55Isaac Katzenelson 7615520461495a8c4fb468aa94d7b18a3fc25d54739rachelzhang @Override 762d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang public void onFabClick(View view){ 7635520461495a8c4fb468aa94d7b18a3fc25d54739rachelzhang rightButtonAction(); 7645520461495a8c4fb468aa94d7b18a3fc25d54739rachelzhang } 7655520461495a8c4fb468aa94d7b18a3fc25d54739rachelzhang 7665520461495a8c4fb468aa94d7b18a3fc25d54739rachelzhang @Override 767d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang public void onLeftButtonClick(View view) { 768d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang final long time = Utils.getTimeNow(); 769d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang final Context context = getActivity().getApplicationContext(); 770d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang final Intent intent = new Intent(context, StopwatchService.class); 771d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang intent.putExtra(Stopwatches.MESSAGE_TIME, time); 772d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang intent.putExtra(Stopwatches.SHOW_NOTIF, false); 773d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang switch (mState) { 774d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang case Stopwatches.STOPWATCH_RUNNING: 775d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang // Save lap time 776d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang addLapTime(time); 777d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang doLap(); 778d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang intent.setAction(Stopwatches.LAP_STOPWATCH); 779d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang context.startService(intent); 780d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang break; 781d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang case Stopwatches.STOPWATCH_STOPPED: 782d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang // do reset 783d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang doReset(); 784d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang intent.setAction(Stopwatches.RESET_STOPWATCH); 785d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang context.startService(intent); 786d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang releaseWakeLock(); 787d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang break; 788d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang default: 789d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang // Happens in monkey tests 790cdbb71b08c13c84af850f4036febc0b90dcfcc7dJustin Klaassen LogUtils.i("Illegal state " + mState + " while pressing the left stopwatch button"); 791d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang break; 792d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang } 793d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang } 794d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang 795d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang @Override 796d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang public void onRightButtonClick(View view) { 797d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang shareResults(); 798d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang } 799d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang 800d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang @Override 8015e469aa155baea98f09d5d5e657aa2315a76679drachelzhang public void setFabAppearance() { 8025e469aa155baea98f09d5d5e657aa2315a76679drachelzhang final DeskClock activity = (DeskClock) getActivity(); 8035e469aa155baea98f09d5d5e657aa2315a76679drachelzhang if (mFab == null || activity.getSelectedTab() != DeskClock.STOPWATCH_TAB_INDEX) { 804d0a9d2681d5386471f59cbe3a3962657266905caBudi Kusmiantoro return; 805d0a9d2681d5386471f59cbe3a3962657266905caBudi Kusmiantoro } 80689b8693723b706636225d042772c80188f4231cdBudi Kusmiantoro if (mState == Stopwatches.STOPWATCH_RUNNING) { 80789b8693723b706636225d042772c80188f4231cdBudi Kusmiantoro mFab.setImageResource(R.drawable.ic_fab_pause); 80889b8693723b706636225d042772c80188f4231cdBudi Kusmiantoro mFab.setContentDescription(getString(R.string.sw_stop_button)); 80989b8693723b706636225d042772c80188f4231cdBudi Kusmiantoro } else { 81089b8693723b706636225d042772c80188f4231cdBudi Kusmiantoro mFab.setImageResource(R.drawable.ic_fab_play); 81189b8693723b706636225d042772c80188f4231cdBudi Kusmiantoro mFab.setContentDescription(getString(R.string.sw_start_button)); 81289b8693723b706636225d042772c80188f4231cdBudi Kusmiantoro } 813d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang mFab.setVisibility(View.VISIBLE); 814d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang } 815d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang 816d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang @Override 8175e469aa155baea98f09d5d5e657aa2315a76679drachelzhang public void setLeftRightButtonAppearance() { 8185e469aa155baea98f09d5d5e657aa2315a76679drachelzhang final DeskClock activity = (DeskClock) getActivity(); 8195e469aa155baea98f09d5d5e657aa2315a76679drachelzhang if (mLeftButton == null || mRightButton == null || 8205e469aa155baea98f09d5d5e657aa2315a76679drachelzhang activity.getSelectedTab() != DeskClock.STOPWATCH_TAB_INDEX) { 821d0a9d2681d5386471f59cbe3a3962657266905caBudi Kusmiantoro return; 822d0a9d2681d5386471f59cbe3a3962657266905caBudi Kusmiantoro } 823d50ff479c37e33de776c339bc93df308f4ac7ab0rachelzhang mRightButton.setImageResource(R.drawable.ic_share); 82489b8693723b706636225d042772c80188f4231cdBudi Kusmiantoro mRightButton.setContentDescription(getString(R.string.sw_share_button)); 8255e469aa155baea98f09d5d5e657aa2315a76679drachelzhang 8265e469aa155baea98f09d5d5e657aa2315a76679drachelzhang switch (mState) { 8275e469aa155baea98f09d5d5e657aa2315a76679drachelzhang case Stopwatches.STOPWATCH_RESET: 8285e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setImageResource(R.drawable.ic_lap); 8295e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setContentDescription(getString(R.string.sw_lap_button)); 8305e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setEnabled(false); 8315e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setVisibility(View.INVISIBLE); 8325e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mRightButton.setVisibility(View.INVISIBLE); 8335e469aa155baea98f09d5d5e657aa2315a76679drachelzhang break; 8345e469aa155baea98f09d5d5e657aa2315a76679drachelzhang case Stopwatches.STOPWATCH_RUNNING: 8355e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setImageResource(R.drawable.ic_lap); 8365e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setContentDescription(getString(R.string.sw_lap_button)); 8375e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setEnabled(!reachedMaxLaps()); 8385e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setVisibility(View.VISIBLE); 8395e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mRightButton.setVisibility(View.INVISIBLE); 8405e469aa155baea98f09d5d5e657aa2315a76679drachelzhang break; 8415e469aa155baea98f09d5d5e657aa2315a76679drachelzhang case Stopwatches.STOPWATCH_STOPPED: 8425e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setImageResource(R.drawable.ic_reset); 8435e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setContentDescription(getString(R.string.sw_reset_button)); 8445e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setEnabled(true); 8455e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mLeftButton.setVisibility(View.VISIBLE); 8465e469aa155baea98f09d5d5e657aa2315a76679drachelzhang mRightButton.setVisibility(View.VISIBLE); 8475e469aa155baea98f09d5d5e657aa2315a76679drachelzhang break; 8485e469aa155baea98f09d5d5e657aa2315a76679drachelzhang } 8495520461495a8c4fb468aa94d7b18a3fc25d54739rachelzhang } 85065d7dfb98ab0102ac899b20fecbc760f2d625608Isaac Katzenelson} 851