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 11 matching lines...) Expand all Loading... | |
41 | 40 |
42 /** | 41 /** |
43 * Interface that the {@link Adapter} uses to interact with the items it man ages. | 42 * Interface that the {@link Adapter} uses to interact with the items it man ages. |
44 */ | 43 */ |
45 public abstract static class TimedItem { | 44 public abstract static class TimedItem { |
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 |
Theresa
2017/02/03 22:36:45
It looks like you need to sync and rebase this CL.
shaktisahu
2017/02/04 18:57:43
Done.
| |
52 /** See {@link #mPosition}. */ | 51 /** See {@link #mPosition}. */ |
53 private final void setPosition(int position) { | 52 public final void setPosition(int position) { |
54 mPosition = position; | 53 mPosition = position; |
55 } | 54 } |
56 | 55 |
57 /** See {@link #mPosition}. */ | 56 /** See {@link #mPosition}. */ |
58 public final int getPosition() { | 57 public final int getPosition() { |
59 return mPosition; | 58 return mPosition; |
60 } | 59 } |
61 | 60 |
62 /** @return The timestamp for this item. */ | 61 /** @return The timestamp for this item. */ |
63 public abstract long getTimestamp(); | 62 public abstract long getTimestamp(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
108 | 107 |
109 protected static class BasicViewHolder extends RecyclerView.ViewHolder { | 108 protected static class BasicViewHolder extends RecyclerView.ViewHolder { |
110 public BasicViewHolder(View itemView) { | 109 public BasicViewHolder(View itemView) { |
111 super(itemView); | 110 super(itemView); |
112 } | 111 } |
113 } | 112 } |
114 | 113 |
115 /** | 114 /** |
116 * A bucket of items with the same date. | 115 * A bucket of items with the same date. |
117 */ | 116 */ |
118 protected static class ItemGroup { | 117 public static class ItemGroup { |
119 private final Date mDate; | 118 private final Date mDate; |
120 private final List<TimedItem> mItems = new ArrayList<>(); | 119 protected final List<TimedItem> mItems = new ArrayList<>(); |
121 | 120 |
122 /** Index of the header, relative to the full list. Must be set only on ce.*/ | 121 /** Index of the header, relative to the full list. Must be set only on ce.*/ |
123 private int mIndex; | 122 private int mIndex; |
124 | 123 |
125 private boolean mIsSorted; | 124 private boolean mIsSorted; |
126 private boolean mIsListHeaderOrFooter; | 125 private boolean mIsListHeaderOrFooter; |
127 | 126 |
128 public ItemGroup(long timestamp) { | 127 public ItemGroup(long timestamp) { |
129 mDate = new Date(timestamp); | 128 mDate = new Date(timestamp); |
130 mIsSorted = true; | 129 mIsSorted = true; |
131 } | 130 } |
132 | 131 |
133 public void addItem(TimedItem item) { | 132 public void addItem(TimedItem item) { |
134 mItems.add(item); | 133 mItems.add(item); |
135 mIsSorted = mItems.size() == 1; | 134 mIsSorted = mItems.size() == 1; |
136 } | 135 } |
137 | 136 |
138 public void removeItem(TimedItem item) { | 137 public void removeItem(TimedItem item) { |
139 mItems.remove(item); | 138 mItems.remove(item); |
140 } | 139 } |
141 | 140 |
142 /** Records the position of all the TimedItems in this group, relative t o the full list. */ | 141 /** Records the position of all the TimedItems in this group, relative t o the full list. */ |
143 public void setPosition(int index) { | 142 public void setPosition(int index) { |
144 assert mIndex == 0 || mIndex == TimedItem.INVALID_POSITION; | 143 assert mIndex == 0 || mIndex == TimedItem.INVALID_POSITION; |
145 mIndex = index; | 144 mIndex = index; |
146 | 145 |
147 sortIfNeeded(); | 146 sortIfNeeded(); |
147 setPositionForItems(index + 1); | |
148 } | |
149 | |
150 protected void setPositionForItems(int startIndex) { | |
151 int index = startIndex; | |
148 for (TimedItem item : mItems) { | 152 for (TimedItem item : mItems) { |
153 item.setPosition(index); | |
149 index += 1; | 154 index += 1; |
150 item.setPosition(index); | |
151 } | 155 } |
152 } | 156 } |
153 | 157 |
154 /** Unsets the position of all TimedItems in this group. */ | 158 /** Unsets the position of all TimedItems in this group. */ |
155 public void resetPosition() { | 159 public void resetPosition() { |
156 mIndex = TimedItem.INVALID_POSITION; | 160 mIndex = TimedItem.INVALID_POSITION; |
157 for (TimedItem item : mItems) item.setPosition(TimedItem.INVALID_POS ITION); | 161 for (TimedItem item : mItems) item.setPosition(TimedItem.INVALID_POS ITION); |
158 } | 162 } |
159 | 163 |
160 /** | 164 /** |
161 * @return Whether the given date happens in the same day as the items i n this group. | 165 * @return Whether the given date happens in the same day as the items i n this group. |
162 */ | 166 */ |
163 public boolean isSameDay(Date otherDate) { | 167 public boolean isSameDay(Date otherDate) { |
164 return compareDate(mDate, otherDate) == 0; | 168 return compareDate(mDate, otherDate) == 0; |
165 } | 169 } |
166 | 170 |
171 protected boolean isListHeaderOrFooter() { | |
Theresa
2017/02/03 19:53:06
Where is this called?
shaktisahu
2017/02/04 18:57:43
Done. Removed. Thanks!
| |
172 return mIsListHeaderOrFooter; | |
173 } | |
174 | |
175 protected Date getDate() { | |
176 return mDate; | |
177 } | |
178 | |
167 /** | 179 /** |
168 * @return The size of this group. | 180 * @return The size of this group. |
169 */ | 181 */ |
170 public int size() { | 182 public int size() { |
171 if (mIsListHeaderOrFooter) return 1; | 183 if (mIsListHeaderOrFooter) return 1; |
172 | 184 |
173 // Plus 1 to account for the date header. | 185 // Plus 1 to account for the date header. |
174 return mItems.size() + 1; | 186 return mItems.size() + 1; |
175 } | 187 } |
176 | 188 |
177 public TimedItem getItemAt(int index) { | 189 public TimedItem getItemAt(int index) { |
178 // 0 is allocated to the date header. The list header has no items. | 190 // 0 is allocated to the date header. The list header has no items. |
179 if (index == 0 || mIsListHeaderOrFooter) return null; | 191 if (index == 0 || mIsListHeaderOrFooter) return null; |
180 | 192 |
181 sortIfNeeded(); | 193 sortIfNeeded(); |
182 return mItems.get(index - 1); | 194 return mItems.get(index - 1); |
183 } | 195 } |
184 | 196 |
185 /** | 197 /** |
186 * Rather than sorting the list each time a new item is added, the list is sorted when | 198 * Rather than sorting the list each time a new item is added, the list is sorted when |
187 * something requires a correct ordering of the items. | 199 * something requires a correct ordering of the items. |
188 */ | 200 */ |
189 private void sortIfNeeded() { | 201 protected void sortIfNeeded() { |
190 if (mIsSorted) return; | 202 if (mIsSorted) return; |
191 mIsSorted = true; | 203 mIsSorted = true; |
192 | 204 |
193 Collections.sort(mItems, new Comparator<TimedItem>() { | 205 Collections.sort(mItems, new Comparator<TimedItem>() { |
194 @Override | 206 @Override |
195 public int compare(TimedItem lhs, TimedItem rhs) { | 207 public int compare(TimedItem lhs, TimedItem rhs) { |
196 // More recent items are listed first. Ideally we'd use Lon g.compare, but that | 208 return compareItem(lhs, rhs); |
197 // is an API level 19 call for some inexplicable reason. | |
198 long timeDelta = lhs.getTimestamp() - rhs.getTimestamp(); | |
199 if (timeDelta > 0) { | |
200 return -1; | |
201 } else if (timeDelta == 0) { | |
202 return 0; | |
203 } else { | |
204 return 1; | |
205 } | |
206 } | 209 } |
207 }); | 210 }); |
208 } | 211 } |
212 | |
213 protected int compareItem(TimedItem lhs, TimedItem rhs) { | |
214 // More recent items are listed first. Ideally we'd use Long.compar e, but that | |
215 // is an API level 19 call for some inexplicable reason. | |
216 long timeDelta = lhs.getTimestamp() - rhs.getTimestamp(); | |
217 if (timeDelta > 0) { | |
218 return -1; | |
219 } else if (timeDelta == 0) { | |
220 return 0; | |
221 } else { | |
222 return 1; | |
223 } | |
224 } | |
225 | |
226 public int getItemViewType(int position) { | |
227 return TYPE_NORMAL; | |
228 } | |
209 } | 229 } |
210 | 230 |
211 // Cached async tasks to get the two Calendar objects, which are used when c omparing dates. | 231 // Cached async tasks to get the two Calendar objects, which are used when c omparing dates. |
212 private static final AsyncTask<Void, Void, Calendar> sCal1 = createCalendar( ); | 232 private static final AsyncTask<Void, Void, Calendar> sCal1 = createCalendar( ); |
213 private static final AsyncTask<Void, Void, Calendar> sCal2 = createCalendar( ); | 233 private static final AsyncTask<Void, Void, Calendar> sCal2 = createCalendar( ); |
214 | 234 |
215 public static final int TYPE_FOOTER = -2; | 235 public static final int TYPE_FOOTER = -2; |
216 public static final int TYPE_HEADER = -1; | 236 public static final int TYPE_HEADER = -1; |
217 public static final int TYPE_DATE = 0; | 237 public static final int TYPE_DATE = 0; |
218 public static final int TYPE_NORMAL = 1; | 238 public static final int TYPE_NORMAL = 1; |
239 public static final int TYPE_SUGGESTED_OFFLINE_PAGES_HEADER = 2; | |
Theresa
2017/02/03 19:53:06
DateDividedAdapter shouldn't know about offline pa
shaktisahu
2017/02/04 18:57:43
Yes, I changed this to TYPE_SUBSECTION which can b
| |
219 | 240 |
220 private int mSize; | 241 private int mSize; |
221 private boolean mHasListHeader; | 242 private boolean mHasListHeader; |
222 private boolean mHasListFooter; | 243 private boolean mHasListFooter; |
223 | 244 |
224 private SortedSet<ItemGroup> mGroups = new TreeSet<>(new Comparator<ItemGrou p>() { | 245 private SortedSet<ItemGroup> mGroups = new TreeSet<>(new Comparator<ItemGrou p>() { |
225 @Override | 246 @Override |
226 public int compare(ItemGroup lhs, ItemGroup rhs) { | 247 public int compare(ItemGroup lhs, ItemGroup rhs) { |
227 return compareDate(lhs.mDate, rhs.mDate); | 248 return compareDate(lhs.mDate, rhs.mDate); |
228 } | 249 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 * {@link #clear(boolean)} to remove previous items. | 288 * {@link #clear(boolean)} to remove previous items. |
268 */ | 289 */ |
269 public void loadItems(List<? extends TimedItem> timedItems) { | 290 public void loadItems(List<? extends TimedItem> timedItems) { |
270 for (TimedItem timedItem : timedItems) { | 291 for (TimedItem timedItem : timedItems) { |
271 Date date = new Date(timedItem.getTimestamp()); | 292 Date date = new Date(timedItem.getTimestamp()); |
272 boolean found = false; | 293 boolean found = false; |
273 for (ItemGroup group : mGroups) { | 294 for (ItemGroup group : mGroups) { |
274 if (group.isSameDay(date)) { | 295 if (group.isSameDay(date)) { |
275 found = true; | 296 found = true; |
276 group.addItem(timedItem); | 297 group.addItem(timedItem); |
277 mSize++; | |
278 break; | 298 break; |
279 } | 299 } |
280 } | 300 } |
281 if (!found) { | 301 if (!found) { |
282 // Create a new ItemGroup with the date for the new item. This i ncreases the | 302 // Create a new ItemGroup with the date for the new item. This i ncreases the |
283 // size by two because we add new views for the date and the ite m itself. | 303 // size by two because we add new views for the date and the ite m itself. |
284 ItemGroup newGroup = new ItemGroup(timedItem.getTimestamp()); | 304 ItemGroup newGroup = createGroup(timedItem.getTimestamp()); |
285 newGroup.addItem(timedItem); | 305 newGroup.addItem(timedItem); |
286 mGroups.add(newGroup); | 306 mGroups.add(newGroup); |
287 mSize += 2; | |
288 } | 307 } |
289 } | 308 } |
290 | 309 |
310 computeItemCount(); | |
291 setGroupPositions(); | 311 setGroupPositions(); |
292 notifyDataSetChanged(); | 312 notifyDataSetChanged(); |
293 } | 313 } |
294 | 314 |
315 protected ItemGroup createGroup(long timeStamp) { | |
316 ItemGroup group = new ItemGroup(timeStamp); | |
317 return group; | |
318 } | |
319 | |
295 /** | 320 /** |
296 * Tells each group where they start in the list. | 321 * Tells each group where they start in the list. |
297 */ | 322 */ |
298 private void setGroupPositions() { | 323 protected void setGroupPositions() { |
299 int startIndex = 0; | 324 int startIndex = 0; |
300 for (ItemGroup group : mGroups) { | 325 for (ItemGroup group : mGroups) { |
301 group.resetPosition(); | 326 group.resetPosition(); |
302 group.setPosition(startIndex); | 327 group.setPosition(startIndex); |
303 startIndex += group.size(); | 328 startIndex += group.size(); |
304 } | 329 } |
305 } | 330 } |
306 | 331 |
307 /** | 332 /** |
308 * Adds a header as the first group in this adapter. | 333 * Adds a header as the first group in this adapter. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
399 } | 424 } |
400 | 425 |
401 @Override | 426 @Override |
402 public final int getItemViewType(int position) { | 427 public final int getItemViewType(int position) { |
403 Pair<ItemGroup, Integer> pair = getGroupAt(position); | 428 Pair<ItemGroup, Integer> pair = getGroupAt(position); |
404 if (pair.second == TYPE_HEADER) { | 429 if (pair.second == TYPE_HEADER) { |
405 return TYPE_HEADER; | 430 return TYPE_HEADER; |
406 } else if (pair.second == TYPE_FOOTER) { | 431 } else if (pair.second == TYPE_FOOTER) { |
407 return TYPE_FOOTER; | 432 return TYPE_FOOTER; |
408 } else if (pair.second == 0) { | 433 } else if (pair.second == 0) { |
409 return TYPE_DATE; | 434 return TYPE_DATE; |
Theresa
2017/02/03 19:53:06
If we're moving the responsibility of knowing the
shaktisahu
2017/02/04 18:57:43
Done.
| |
410 } else { | 435 } else { |
411 return TYPE_NORMAL; | 436 ItemGroup group = pair.first; |
437 return group.getItemViewType(pair.second); | |
412 } | 438 } |
413 } | 439 } |
414 | 440 |
415 @Override | 441 @Override |
416 public final RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, in t viewType) { | 442 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int view Type) { |
417 if (viewType == TYPE_DATE) { | 443 if (viewType == TYPE_DATE) { |
418 return new DateViewHolder(LayoutInflater.from(parent.getContext()).i nflate( | 444 return new DateViewHolder(LayoutInflater.from(parent.getContext()).i nflate( |
419 getTimedItemViewResId(), parent, false)); | 445 getTimedItemViewResId(), parent, false)); |
420 } else if (viewType == TYPE_NORMAL) { | 446 } else if (viewType == TYPE_NORMAL) { |
421 return createViewHolder(parent); | 447 return createViewHolder(parent); |
422 } else if (viewType == TYPE_HEADER) { | 448 } else if (viewType == TYPE_HEADER) { |
423 return createHeader(parent); | 449 return createHeader(parent); |
424 } else if (viewType == TYPE_FOOTER) { | 450 } else if (viewType == TYPE_FOOTER) { |
425 return createFooter(parent); | 451 return createFooter(parent); |
426 } | 452 } |
427 assert false; | 453 assert false; |
428 return null; | 454 return null; |
429 } | 455 } |
430 | 456 |
431 @Override | 457 @Override |
432 public final void onBindViewHolder(RecyclerView.ViewHolder holder, int posit ion) { | 458 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { |
433 Pair<Date, TimedItem> pair = getItemAt(position); | 459 Pair<Date, TimedItem> pair = getItemAt(position); |
434 if (holder instanceof DateViewHolder) { | 460 if (holder instanceof DateViewHolder) { |
435 ((DateViewHolder) holder).setDate(pair.first); | 461 ((DateViewHolder) holder).setDate(pair.first); |
436 } else if (!(holder instanceof BasicViewHolder)) { | 462 } else if (!(holder instanceof BasicViewHolder)) { |
437 bindViewHolderForTimedItem(holder, pair.second); | 463 bindViewHolderForTimedItem(holder, pair.second); |
438 } | 464 } |
439 } | 465 } |
440 | 466 |
441 @Override | 467 @Override |
442 public final int getItemCount() { | 468 public final int getItemCount() { |
(...skipping 24 matching lines...) Expand all Loading... | |
467 assert false; | 493 assert false; |
468 return null; | 494 return null; |
469 } | 495 } |
470 | 496 |
471 /** | 497 /** |
472 * @param item The item to remove from the adapter. | 498 * @param item The item to remove from the adapter. |
473 */ | 499 */ |
474 protected void removeItem(TimedItem item) { | 500 protected void removeItem(TimedItem item) { |
475 ItemGroup group = getGroupAt(item.getPosition()).first; | 501 ItemGroup group = getGroupAt(item.getPosition()).first; |
476 group.removeItem(item); | 502 group.removeItem(item); |
477 mSize--; | |
478 | 503 |
479 // Remove the group if only the date header is left. | 504 // Remove the group if only the date header is left. |
480 if (group.size() == 1) { | 505 if (group.size() == 1) { |
481 mGroups.remove(group); | 506 mGroups.remove(group); |
482 mSize--; | |
483 } | 507 } |
484 | 508 |
509 computeItemCount(); | |
485 setGroupPositions(); | 510 setGroupPositions(); |
486 notifyDataSetChanged(); | 511 notifyDataSetChanged(); |
487 } | 512 } |
488 | 513 |
514 protected void computeItemCount() { | |
515 mSize = 0; | |
516 for (ItemGroup group : mGroups) { | |
517 mSize += group.size(); | |
518 } | |
519 } | |
520 | |
489 /** | 521 /** |
490 * Creates a long ID that identifies a particular day in history. | 522 * Creates a long ID that identifies a particular day in history. |
491 * @param date Date to process. | 523 * @param date Date to process. |
492 * @return Long that has the day of the year (1-365) in the lowest 16 bits a nd the year in the | 524 * @return Long that has the day of the year (1-365) in the lowest 16 bits a nd the year in the |
493 * next 16 bits over. | 525 * next 16 bits over. |
494 */ | 526 */ |
495 private static long getStableIdFromDate(Date date) { | 527 private static long getStableIdFromDate(Date date) { |
496 Pair<Calendar, Calendar> pair = getCachedCalendars(); | 528 Pair<Calendar, Calendar> pair = getCachedCalendars(); |
497 Calendar calendar = pair.first; | 529 Calendar calendar = pair.first; |
498 calendar.setTime(date); | 530 calendar.setTime(date); |
499 long dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); | 531 long dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); |
500 long year = calendar.get(Calendar.YEAR); | 532 long year = calendar.get(Calendar.YEAR); |
501 return (year << 16) + dayOfYear; | 533 return (year << 16) + dayOfYear; |
502 } | 534 } |
503 | 535 |
504 /** | 536 /** |
505 * Compares two {@link Date}s. Note if you already have two {@link Calendar} objects, use | 537 * Compares two {@link Date}s. Note if you already have two {@link Calendar} objects, use |
506 * {@link #compareCalendar(Calendar, Calendar)} instead. | 538 * {@link #compareCalendar(Calendar, Calendar)} instead. |
507 * @return 0 if date1 and date2 are in the same day; 1 if date1 is before da te2; -1 otherwise. | 539 * @return 0 if date1 and date2 are in the same day; 1 if date1 is before da te2; -1 otherwise. |
508 */ | 540 */ |
509 private static int compareDate(Date date1, Date date2) { | 541 protected static int compareDate(Date date1, Date date2) { |
510 Pair<Calendar, Calendar> pair = getCachedCalendars(); | 542 Pair<Calendar, Calendar> pair = getCachedCalendars(); |
511 Calendar cal1 = pair.first, cal2 = pair.second; | 543 Calendar cal1 = pair.first, cal2 = pair.second; |
512 cal1.setTime(date1); | 544 cal1.setTime(date1); |
513 cal2.setTime(date2); | 545 cal2.setTime(date2); |
514 return compareCalendar(cal1, cal2); | 546 return compareCalendar(cal1, cal2); |
515 } | 547 } |
516 | 548 |
517 /** | 549 /** |
518 * @return 0 if cal1 and cal2 are in the same day; 1 if cal1 happens before cal2; -1 otherwise. | 550 * @return 0 if cal1 and cal2 are in the same day; 1 if cal1 happens before cal2; -1 otherwise. |
519 */ | 551 */ |
(...skipping 30 matching lines...) Expand all Loading... | |
550 */ | 582 */ |
551 private static AsyncTask<Void, Void, Calendar> createCalendar() { | 583 private static AsyncTask<Void, Void, Calendar> createCalendar() { |
552 return new AsyncTask<Void, Void, Calendar>() { | 584 return new AsyncTask<Void, Void, Calendar>() { |
553 @Override | 585 @Override |
554 protected Calendar doInBackground(Void... unused) { | 586 protected Calendar doInBackground(Void... unused) { |
555 return Calendar.getInstance(); | 587 return Calendar.getInstance(); |
556 } | 588 } |
557 }.execute(); | 589 }.execute(); |
558 } | 590 } |
559 } | 591 } |
OLD | NEW |