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