OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.widget; | 5 package org.chromium.chrome.browser.widget; |
6 | 6 |
7 import android.os.AsyncTask; | 7 import android.os.AsyncTask; |
8 import android.support.v7.widget.RecyclerView; | 8 import android.support.v7.widget.RecyclerView; |
9 import android.support.v7.widget.RecyclerView.Adapter; | 9 import android.support.v7.widget.RecyclerView.Adapter; |
10 import android.support.v7.widget.RecyclerView.ViewHolder; | 10 import android.support.v7.widget.RecyclerView.ViewHolder; |
11 import android.text.format.DateUtils; | 11 import android.text.format.DateUtils; |
12 import android.util.Pair; | 12 import android.util.Pair; |
13 import android.view.LayoutInflater; | 13 import android.view.LayoutInflater; |
14 import android.view.View; | 14 import android.view.View; |
15 import android.view.ViewGroup; | 15 import android.view.ViewGroup; |
16 import android.widget.TextView; | 16 import android.widget.TextView; |
17 | 17 |
18 import org.chromium.chrome.R; | 18 import org.chromium.chrome.R; |
19 import org.chromium.chrome.browser.widget.DateDividedAdapter.ItemGroup; | |
20 | 19 |
21 import java.util.ArrayList; | 20 import java.util.ArrayList; |
22 import java.util.Calendar; | 21 import java.util.Calendar; |
23 import java.util.Collections; | 22 import java.util.Collections; |
24 import java.util.Comparator; | 23 import java.util.Comparator; |
25 import java.util.Date; | 24 import java.util.Date; |
26 import java.util.List; | 25 import java.util.List; |
27 import java.util.SortedSet; | 26 import java.util.SortedSet; |
28 import java.util.TreeSet; | 27 import java.util.TreeSet; |
29 import java.util.concurrent.ExecutionException; | 28 import java.util.concurrent.ExecutionException; |
(...skipping 16 matching lines...) Expand all Loading... | |
46 /** Value indicating that a TimedItem is not currently being displayed. */ | 45 /** Value indicating that a TimedItem is not currently being displayed. */ |
47 public static final int INVALID_POSITION = -1; | 46 public static final int INVALID_POSITION = -1; |
48 | 47 |
49 /** Position of the TimedItem in the list, or {@link #INVALID_POSITION} if not shown. */ | 48 /** Position of the TimedItem in the list, or {@link #INVALID_POSITION} if not shown. */ |
50 private int mPosition = INVALID_POSITION; | 49 private int mPosition = INVALID_POSITION; |
51 | 50 |
52 private boolean mIsFirstInGroup; | 51 private boolean mIsFirstInGroup; |
53 private boolean mIsLastInGroup; | 52 private boolean mIsLastInGroup; |
54 | 53 |
55 /** See {@link #mPosition}. */ | 54 /** See {@link #mPosition}. */ |
56 private final void setPosition(int position) { | 55 public final void setPosition(int position) { |
57 mPosition = position; | 56 mPosition = position; |
58 } | 57 } |
59 | 58 |
60 /** See {@link #mPosition}. */ | 59 /** See {@link #mPosition}. */ |
61 public final int getPosition() { | 60 public final int getPosition() { |
62 return mPosition; | 61 return mPosition; |
63 } | 62 } |
64 | 63 |
65 /** | 64 /** |
66 * @param isFirst Whether this item is the first in its group. | 65 * @param isFirst Whether this item is the first in its group. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 | 144 |
146 protected static class BasicViewHolder extends RecyclerView.ViewHolder { | 145 protected static class BasicViewHolder extends RecyclerView.ViewHolder { |
147 public BasicViewHolder(View itemView) { | 146 public BasicViewHolder(View itemView) { |
148 super(itemView); | 147 super(itemView); |
149 } | 148 } |
150 } | 149 } |
151 | 150 |
152 /** | 151 /** |
153 * A bucket of items with the same date. | 152 * A bucket of items with the same date. |
154 */ | 153 */ |
155 protected static class ItemGroup { | 154 public static class ItemGroup { |
156 private final Date mDate; | 155 protected final Date mDate; |
157 private final List<TimedItem> mItems = new ArrayList<>(); | 156 protected final List<TimedItem> mItems = new ArrayList<>(); |
158 | 157 |
159 /** Index of the header, relative to the full list. Must be set only on ce.*/ | 158 /** Index of the header, relative to the full list. Must be set only on ce.*/ |
160 private int mIndex; | 159 private int mIndex; |
161 | 160 |
162 private boolean mIsSorted; | 161 private boolean mIsSorted; |
163 private boolean mIsListHeader; | 162 private boolean mIsListHeader; |
164 private boolean mIsListFooter; | 163 private boolean mIsListFooter; |
165 | 164 |
166 public ItemGroup(long timestamp) { | 165 public ItemGroup(long timestamp) { |
167 mDate = new Date(timestamp); | 166 mDate = new Date(timestamp); |
168 mIsSorted = true; | 167 mIsSorted = true; |
169 } | 168 } |
170 | 169 |
171 public void addItem(TimedItem item) { | 170 public void addItem(TimedItem item) { |
172 mItems.add(item); | 171 mItems.add(item); |
173 mIsSorted = mItems.size() == 1; | 172 mIsSorted = mItems.size() == 1; |
174 } | 173 } |
175 | 174 |
176 public void removeItem(TimedItem item) { | 175 public void removeItem(TimedItem item) { |
177 mItems.remove(item); | 176 mItems.remove(item); |
178 } | 177 } |
179 | 178 |
180 /** Records the position of all the TimedItems in this group, relative t o the full list. */ | 179 /** Records the position of all the TimedItems in this group, relative t o the full list. */ |
181 public void setPosition(int index) { | 180 public void setPosition(int index) { |
182 assert mIndex == 0 || mIndex == TimedItem.INVALID_POSITION; | 181 assert mIndex == 0 || mIndex == TimedItem.INVALID_POSITION; |
183 mIndex = index; | 182 mIndex = index; |
184 | 183 |
185 sortIfNeeded(); | 184 sortIfNeeded(); |
185 setPositionForItems(index + 1); | |
186 markFirstAndLastItem(); | |
187 } | |
188 | |
189 protected void setPositionForItems(int startIndex) { | |
190 int index = startIndex; | |
186 for (int i = 0; i < mItems.size(); i++) { | 191 for (int i = 0; i < mItems.size(); i++) { |
187 index += 1; | |
188 TimedItem item = mItems.get(i); | 192 TimedItem item = mItems.get(i); |
189 item.setPosition(index); | 193 item.setPosition(index); |
190 item.setIsFirstInGroup(i == 0); | 194 index += 1; |
191 item.setIsLastInGroup(i == mItems.size() - 1); | |
192 } | 195 } |
193 } | 196 } |
194 | 197 |
198 protected void markFirstAndLastItem() { | |
199 TimedItem first = mItems.get(0); | |
200 TimedItem last = mItems.get(mItems.size() - 1); | |
201 first.setIsFirstInGroup(true); | |
202 last.setIsLastInGroup(true); | |
203 } | |
204 | |
195 /** Unsets the position of all TimedItems in this group. */ | 205 /** Unsets the position of all TimedItems in this group. */ |
196 public void resetPosition() { | 206 public void resetPosition() { |
197 mIndex = TimedItem.INVALID_POSITION; | 207 mIndex = TimedItem.INVALID_POSITION; |
198 for (TimedItem item : mItems) item.setPosition(TimedItem.INVALID_POS ITION); | 208 for (TimedItem item : mItems) item.setPosition(TimedItem.INVALID_POS ITION); |
199 } | 209 } |
200 | 210 |
201 /** | 211 /** |
202 * @return Whether the given date happens in the same day as the items i n this group. | 212 * @return Whether the given date happens in the same day as the items i n this group. |
203 */ | 213 */ |
204 public boolean isSameDay(Date otherDate) { | 214 public boolean isSameDay(Date otherDate) { |
205 return compareDate(mDate, otherDate) == 0; | 215 return compareDate(mDate, otherDate) == 0; |
206 } | 216 } |
207 | 217 |
208 /** | 218 /** |
209 * @return The size of this group. | 219 * @return The size of this group. |
210 */ | 220 */ |
211 public int size() { | 221 public int size() { |
212 if (mIsListHeader || mIsListFooter) return 1; | 222 if (mIsListHeader || mIsListFooter) return 1; |
213 | 223 |
214 // Plus 1 to account for the date header. | 224 // Plus 1 to account for the date header. |
215 return mItems.size() + 1; | 225 return mItems.isEmpty() ? 0 : mItems.size() + 1; |
216 } | 226 } |
217 | 227 |
218 public TimedItem getItemAt(int index) { | 228 public TimedItem getItemAt(int index) { |
219 // 0 is allocated to the date header. The list header has no items. | 229 // 0 is allocated to the date header. The list header has no items. |
220 if (index == 0 || mIsListHeader || mIsListFooter) return null; | 230 if (index == 0 || mIsListHeader || mIsListFooter) return null; |
221 | 231 |
222 sortIfNeeded(); | 232 sortIfNeeded(); |
233 return getItemAtInternal(index); | |
234 } | |
235 | |
236 protected TimedItem getItemAtInternal(int index) { | |
223 return mItems.get(index - 1); | 237 return mItems.get(index - 1); |
224 } | 238 } |
225 | 239 |
226 /** | 240 /** |
227 * Rather than sorting the list each time a new item is added, the list is sorted when | 241 * Rather than sorting the list each time a new item is added, the list is sorted when |
228 * something requires a correct ordering of the items. | 242 * something requires a correct ordering of the items. |
229 */ | 243 */ |
230 private void sortIfNeeded() { | 244 protected void sortIfNeeded() { |
231 if (mIsSorted) return; | 245 if (mIsSorted) return; |
232 mIsSorted = true; | 246 mIsSorted = true; |
233 | 247 |
234 Collections.sort(mItems, new Comparator<TimedItem>() { | 248 Collections.sort(mItems, new Comparator<TimedItem>() { |
235 @Override | 249 @Override |
236 public int compare(TimedItem lhs, TimedItem rhs) { | 250 public int compare(TimedItem lhs, TimedItem rhs) { |
237 // More recent items are listed first. Ideally we'd use Lon g.compare, but that | 251 return compareItem(lhs, rhs); |
238 // is an API level 19 call for some inexplicable reason. | |
239 long timeDelta = lhs.getTimestamp() - rhs.getTimestamp(); | |
240 if (timeDelta > 0) { | |
241 return -1; | |
242 } else if (timeDelta == 0) { | |
243 return 0; | |
244 } else { | |
245 return 1; | |
246 } | |
247 } | 252 } |
248 }); | 253 }); |
249 } | 254 } |
255 | |
256 protected int compareItem(TimedItem lhs, TimedItem rhs) { | |
257 // More recent items are listed first. Ideally we'd use Long.compar e, but that | |
258 // is an API level 19 call for some inexplicable reason. | |
259 long timeDelta = lhs.getTimestamp() - rhs.getTimestamp(); | |
260 if (timeDelta > 0) { | |
261 return -1; | |
262 } else if (timeDelta == 0) { | |
263 return 0; | |
264 } else { | |
265 return 1; | |
266 } | |
267 } | |
268 | |
269 public int getItemViewType(int position) { | |
270 return position == 0 ? TYPE_DATE : TYPE_NORMAL; | |
271 } | |
272 | |
273 /** | |
274 * Returns the number of rows that should be removed when the given item is deleted. | |
275 * e.g. When the last item is deleted, the date header should also be re moved. | |
276 * @param item The item to be removed. | |
277 * @return The number of rows to be removed. | |
278 */ | |
279 public int getNumberOfRowsToBeRemovedForItem(TimedItem item) { | |
Theresa
2017/02/13 19:15:00
Instead of introducing this method, can ItemGroup#
| |
280 return mItems.size() == 1 ? 2 : 1; | |
281 } | |
250 } | 282 } |
251 | 283 |
252 // Cached async tasks to get the two Calendar objects, which are used when c omparing dates. | 284 // Cached async tasks to get the two Calendar objects, which are used when c omparing dates. |
253 private static final AsyncTask<Void, Void, Calendar> sCal1 = createCalendar( ); | 285 private static final AsyncTask<Void, Void, Calendar> sCal1 = createCalendar( ); |
254 private static final AsyncTask<Void, Void, Calendar> sCal2 = createCalendar( ); | 286 private static final AsyncTask<Void, Void, Calendar> sCal2 = createCalendar( ); |
255 | 287 |
256 public static final int TYPE_FOOTER = -2; | 288 public static final int TYPE_FOOTER = -2; |
257 public static final int TYPE_HEADER = -1; | 289 public static final int TYPE_HEADER = -1; |
258 public static final int TYPE_DATE = 0; | 290 public static final int TYPE_DATE = 0; |
259 public static final int TYPE_NORMAL = 1; | 291 public static final int TYPE_NORMAL = 1; |
292 public static final int TYPE_SUBSECTION_HEADER = 2; | |
260 | 293 |
261 private int mSize; | 294 private int mSize; |
262 private boolean mHasListHeader; | 295 private boolean mHasListHeader; |
263 private boolean mHasListFooter; | 296 private boolean mHasListFooter; |
264 | 297 |
265 private SortedSet<ItemGroup> mGroups = new TreeSet<>(new Comparator<ItemGrou p>() { | 298 private SortedSet<ItemGroup> mGroups = new TreeSet<>(new Comparator<ItemGrou p>() { |
266 @Override | 299 @Override |
267 public int compare(ItemGroup lhs, ItemGroup rhs) { | 300 public int compare(ItemGroup lhs, ItemGroup rhs) { |
268 if (lhs == rhs) return 0; | 301 if (lhs == rhs) return 0; |
269 | 302 |
270 // There should only be at most one list header and one list footer in the SortedSet. | 303 // There should only be at most one list header and one list footer in the SortedSet. |
271 if (lhs.mIsListHeader || rhs.mIsListFooter) return -1; | 304 if (lhs.mIsListHeader || rhs.mIsListFooter) return -1; |
272 if (lhs.mIsListFooter || rhs.mIsListHeader) return 1; | 305 if (lhs.mIsListFooter || rhs.mIsListHeader) return 1; |
273 | 306 |
274 return compareDate(lhs.mDate, rhs.mDate); | 307 return compareDate(lhs.mDate, rhs.mDate); |
275 } | 308 } |
276 }); | 309 }); |
277 | 310 |
278 /** | 311 /** |
279 * Creates a {@link ViewHolder} in the given view parent. | 312 * Creates a {@link ViewHolder} in the given view parent. |
280 * @see #onCreateViewHolder(ViewGroup, int) | 313 * @see #onCreateViewHolder(ViewGroup, int) |
281 */ | 314 */ |
282 protected abstract ViewHolder createViewHolder(ViewGroup parent); | 315 protected abstract ViewHolder createViewHolder(ViewGroup parent); |
283 | 316 |
284 /** | 317 /** |
318 * Creates a {@link ViewHolder} for a subsection in the given view parent. | |
319 * @see #onCreateViewHolder(ViewGroup, int) | |
320 */ | |
321 protected ViewHolder createSubsectionHeader(ViewGroup parent) { | |
322 return null; | |
323 } | |
324 | |
325 /** | |
285 * Creates a {@link BasicViewHolder} in the given view parent for the header . | 326 * Creates a {@link BasicViewHolder} in the given view parent for the header . |
286 * @see #onCreateViewHolder(ViewGroup, int) | 327 * @see #onCreateViewHolder(ViewGroup, int) |
287 */ | 328 */ |
288 protected BasicViewHolder createHeader(ViewGroup parent) { | 329 protected BasicViewHolder createHeader(ViewGroup parent) { |
289 return null; | 330 return null; |
290 } | 331 } |
291 | 332 |
292 /** | 333 /** |
293 * Creates a {@link BasicViewHolder} in the given view parent for the footer . | 334 * Creates a {@link BasicViewHolder} in the given view parent for the footer . |
294 * See {@link #onCreateViewHolder(ViewGroup, int)}. | 335 * See {@link #onCreateViewHolder(ViewGroup, int)}. |
(...skipping 28 matching lines...) Expand all Loading... | |
323 * {@link #clear(boolean)} to remove previous items. | 364 * {@link #clear(boolean)} to remove previous items. |
324 */ | 365 */ |
325 public void loadItems(List<? extends TimedItem> timedItems) { | 366 public void loadItems(List<? extends TimedItem> timedItems) { |
326 for (TimedItem timedItem : timedItems) { | 367 for (TimedItem timedItem : timedItems) { |
327 Date date = new Date(timedItem.getTimestamp()); | 368 Date date = new Date(timedItem.getTimestamp()); |
328 boolean found = false; | 369 boolean found = false; |
329 for (ItemGroup group : mGroups) { | 370 for (ItemGroup group : mGroups) { |
330 if (group.isSameDay(date)) { | 371 if (group.isSameDay(date)) { |
331 found = true; | 372 found = true; |
332 group.addItem(timedItem); | 373 group.addItem(timedItem); |
333 mSize++; | |
334 break; | 374 break; |
335 } | 375 } |
336 } | 376 } |
337 if (!found) { | 377 if (!found) { |
338 // Create a new ItemGroup with the date for the new item. This i ncreases the | 378 // Create a new ItemGroup with the date for the new item. This i ncreases the |
339 // size by two because we add new views for the date and the ite m itself. | 379 // size by two because we add new views for the date and the ite m itself. |
340 ItemGroup newGroup = new ItemGroup(timedItem.getTimestamp()); | 380 ItemGroup newGroup = createGroup(timedItem.getTimestamp()); |
341 newGroup.addItem(timedItem); | 381 newGroup.addItem(timedItem); |
342 mGroups.add(newGroup); | 382 mGroups.add(newGroup); |
343 mSize += 2; | |
344 } | 383 } |
345 } | 384 } |
346 | 385 |
386 computeItemCount(); | |
347 setGroupPositions(); | 387 setGroupPositions(); |
348 notifyDataSetChanged(); | 388 notifyDataSetChanged(); |
349 } | 389 } |
350 | 390 |
391 protected ItemGroup createGroup(long timestamp) { | |
392 return new ItemGroup(timestamp); | |
393 } | |
394 | |
351 /** | 395 /** |
352 * Tells each group where they start in the list. | 396 * Tells each group where they start in the list. |
353 */ | 397 */ |
354 private void setGroupPositions() { | 398 protected void setGroupPositions() { |
355 int startIndex = 0; | 399 int startIndex = 0; |
356 for (ItemGroup group : mGroups) { | 400 for (ItemGroup group : mGroups) { |
357 group.resetPosition(); | 401 group.resetPosition(); |
358 group.setPosition(startIndex); | 402 group.setPosition(startIndex); |
359 startIndex += group.size(); | 403 startIndex += group.size(); |
360 } | 404 } |
361 } | 405 } |
362 | 406 |
363 /** | 407 /** |
364 * Adds a header as the first group in this adapter. | 408 * Adds a header as the first group in this adapter. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 return new Pair<>(group.mDate, group.getItemAt(pair.second)); | 498 return new Pair<>(group.mDate, group.getItemAt(pair.second)); |
455 } | 499 } |
456 | 500 |
457 @Override | 501 @Override |
458 public final int getItemViewType(int position) { | 502 public final int getItemViewType(int position) { |
459 Pair<ItemGroup, Integer> pair = getGroupAt(position); | 503 Pair<ItemGroup, Integer> pair = getGroupAt(position); |
460 if (pair.second == TYPE_HEADER) { | 504 if (pair.second == TYPE_HEADER) { |
461 return TYPE_HEADER; | 505 return TYPE_HEADER; |
462 } else if (pair.second == TYPE_FOOTER) { | 506 } else if (pair.second == TYPE_FOOTER) { |
463 return TYPE_FOOTER; | 507 return TYPE_FOOTER; |
464 } else if (pair.second == 0) { | |
465 return TYPE_DATE; | |
466 } else { | 508 } else { |
467 return TYPE_NORMAL; | 509 ItemGroup group = pair.first; |
510 return group.getItemViewType(pair.second); | |
468 } | 511 } |
469 } | 512 } |
470 | 513 |
471 @Override | 514 @Override |
472 public final RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, in t viewType) { | 515 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int view Type) { |
473 if (viewType == TYPE_DATE) { | 516 if (viewType == TYPE_DATE) { |
474 return createDateViewHolder(parent); | 517 return createDateViewHolder(parent); |
475 } else if (viewType == TYPE_NORMAL) { | 518 } else if (viewType == TYPE_NORMAL) { |
476 return createViewHolder(parent); | 519 return createViewHolder(parent); |
477 } else if (viewType == TYPE_HEADER) { | 520 } else if (viewType == TYPE_HEADER) { |
478 return createHeader(parent); | 521 return createHeader(parent); |
479 } else if (viewType == TYPE_FOOTER) { | 522 } else if (viewType == TYPE_FOOTER) { |
480 return createFooter(parent); | 523 return createFooter(parent); |
524 } else if (viewType == TYPE_SUBSECTION_HEADER) { | |
525 return createSubsectionHeader(parent); | |
481 } | 526 } |
482 assert false; | 527 assert false; |
483 return null; | 528 return null; |
484 } | 529 } |
485 | 530 |
486 @Override | 531 @Override |
487 public final void onBindViewHolder(RecyclerView.ViewHolder holder, int posit ion) { | 532 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { |
488 Pair<Date, TimedItem> pair = getItemAt(position); | 533 Pair<Date, TimedItem> pair = getItemAt(position); |
489 if (holder instanceof DateViewHolder) { | 534 if (holder instanceof DateViewHolder) { |
490 ((DateViewHolder) holder).setDate(pair.first); | 535 ((DateViewHolder) holder).setDate(pair.first); |
491 } else if (!(holder instanceof BasicViewHolder)) { | 536 } else if (!(holder instanceof BasicViewHolder)) { |
492 bindViewHolderForTimedItem(holder, pair.second); | 537 bindViewHolderForTimedItem(holder, pair.second); |
493 } | 538 } |
494 } | 539 } |
495 | 540 |
496 @Override | 541 @Override |
497 public final int getItemCount() { | 542 public final int getItemCount() { |
(...skipping 25 matching lines...) Expand all Loading... | |
523 } | 568 } |
524 assert false; | 569 assert false; |
525 return null; | 570 return null; |
526 } | 571 } |
527 | 572 |
528 /** | 573 /** |
529 * @param item The item to remove from the adapter. | 574 * @param item The item to remove from the adapter. |
530 */ | 575 */ |
531 protected void removeItem(TimedItem item) { | 576 protected void removeItem(TimedItem item) { |
532 ItemGroup group = getGroupAt(item.getPosition()).first; | 577 ItemGroup group = getGroupAt(item.getPosition()).first; |
578 int numRowsToRemove = group.getNumberOfRowsToBeRemovedForItem(item); | |
533 group.removeItem(item); | 579 group.removeItem(item); |
534 mSize--; | |
535 | 580 |
536 // Remove the group if only the date header is left. | 581 // Remove the group if it is empty. |
537 if (group.size() == 1) { | 582 if (group.size() == 0) { |
538 mGroups.remove(group); | 583 mGroups.remove(group); |
539 mSize--; | |
540 } | 584 } |
541 | 585 |
586 mSize -= numRowsToRemove; | |
542 setGroupPositions(); | 587 setGroupPositions(); |
543 notifyDataSetChanged(); | 588 notifyDataSetChanged(); |
544 } | 589 } |
545 | 590 |
591 protected void computeItemCount() { | |
592 mSize = 0; | |
593 for (ItemGroup group : mGroups) { | |
594 mSize += group.size(); | |
595 } | |
596 } | |
597 | |
546 /** | 598 /** |
547 * Creates a long ID that identifies a particular day in history. | 599 * Creates a long ID that identifies a particular day in history. |
548 * @param date Date to process. | 600 * @param date Date to process. |
549 * @return Long that has the day of the year (1-365) in the lowest 16 bits a nd the year in the | 601 * @return Long that has the day of the year (1-365) in the lowest 16 bits a nd the year in the |
550 * next 16 bits over. | 602 * next 16 bits over. |
551 */ | 603 */ |
552 private static long getStableIdFromDate(Date date) { | 604 private static long getStableIdFromDate(Date date) { |
553 Pair<Calendar, Calendar> pair = getCachedCalendars(); | 605 Pair<Calendar, Calendar> pair = getCachedCalendars(); |
554 Calendar calendar = pair.first; | 606 Calendar calendar = pair.first; |
555 calendar.setTime(date); | 607 calendar.setTime(date); |
556 long dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); | 608 long dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); |
557 long year = calendar.get(Calendar.YEAR); | 609 long year = calendar.get(Calendar.YEAR); |
558 return (year << 16) + dayOfYear; | 610 return (year << 16) + dayOfYear; |
559 } | 611 } |
560 | 612 |
561 /** | 613 /** |
562 * Compares two {@link Date}s. Note if you already have two {@link Calendar} objects, use | 614 * Compares two {@link Date}s. Note if you already have two {@link Calendar} objects, use |
563 * {@link #compareCalendar(Calendar, Calendar)} instead. | 615 * {@link #compareCalendar(Calendar, Calendar)} instead. |
564 * @return 0 if date1 and date2 are in the same day; 1 if date1 is before da te2; -1 otherwise. | 616 * @return 0 if date1 and date2 are in the same day; 1 if date1 is before da te2; -1 otherwise. |
565 */ | 617 */ |
566 private static int compareDate(Date date1, Date date2) { | 618 protected static int compareDate(Date date1, Date date2) { |
567 Pair<Calendar, Calendar> pair = getCachedCalendars(); | 619 Pair<Calendar, Calendar> pair = getCachedCalendars(); |
568 Calendar cal1 = pair.first, cal2 = pair.second; | 620 Calendar cal1 = pair.first, cal2 = pair.second; |
569 cal1.setTime(date1); | 621 cal1.setTime(date1); |
570 cal2.setTime(date2); | 622 cal2.setTime(date2); |
571 return compareCalendar(cal1, cal2); | 623 return compareCalendar(cal1, cal2); |
572 } | 624 } |
573 | 625 |
574 /** | 626 /** |
575 * @return 0 if cal1 and cal2 are in the same day; 1 if cal1 happens before cal2; -1 otherwise. | 627 * @return 0 if cal1 and cal2 are in the same day; 1 if cal1 happens before cal2; -1 otherwise. |
576 */ | 628 */ |
(...skipping 30 matching lines...) Expand all Loading... | |
607 */ | 659 */ |
608 private static AsyncTask<Void, Void, Calendar> createCalendar() { | 660 private static AsyncTask<Void, Void, Calendar> createCalendar() { |
609 return new AsyncTask<Void, Void, Calendar>() { | 661 return new AsyncTask<Void, Void, Calendar>() { |
610 @Override | 662 @Override |
611 protected Calendar doInBackground(Void... unused) { | 663 protected Calendar doInBackground(Void... unused) { |
612 return Calendar.getInstance(); | 664 return Calendar.getInstance(); |
613 } | 665 } |
614 }.execute(); | 666 }.execute(); |
615 } | 667 } |
616 } | 668 } |
OLD | NEW |