summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wei <markwei@google.com>2013-07-09 16:00:00 -0700
committerMark Wei <markwei@google.com>2013-07-12 14:00:40 -0700
commit81aea35d45b3d0191ec595562a2fcf67009845d5 (patch)
treeae690fd5a9a8aee3e2a842fe53e08f67433701aa
parenta2fb3206037770eb4797c3b059d52bd862b40e44 (diff)
downloadandroid_packages_apps_UnifiedEmail-81aea35d45b3d0191ec595562a2fcf67009845d5.tar.gz
android_packages_apps_UnifiedEmail-81aea35d45b3d0191ec595562a2fcf67009845d5.tar.bz2
android_packages_apps_UnifiedEmail-81aea35d45b3d0191ec595562a2fcf67009845d5.zip
Final UI for Attachment Previews.
Placeholder pulsates for images not yet loaded. One images loads at a time, that one image will display a spinning progressbar after a delay. Progress bar fixes to ensure it is rotates smoothly. Clear section before drawing to it so transparent images look right. Avoid PhotoManager load loop. Bug: 9745486 Bug: 9816053 Change-Id: I2e65b3e3484d6da47d4e2523404dc745b99dd04c
-rw-r--r--res/drawable-hdpi/ic_attachment_load.pngbin0 -> 725 bytes
-rw-r--r--res/drawable-hdpi/ic_spinner_inner_holo.pngbin0 -> 2674 bytes
-rw-r--r--res/drawable-hdpi/ic_spinner_outer_holo.pngbin0 -> 2789 bytes
-rw-r--r--res/drawable-mdpi/ic_attachment_load.pngbin0 -> 626 bytes
-rw-r--r--res/drawable-mdpi/ic_spinner_inner_holo.pngbin0 -> 1826 bytes
-rw-r--r--res/drawable-mdpi/ic_spinner_outer_holo.pngbin0 -> 1925 bytes
-rw-r--r--res/drawable-xhdpi/ic_attachment_load.pngbin0 -> 840 bytes
-rw-r--r--res/drawable-xhdpi/ic_spinner_inner_holo.pngbin0 -> 3275 bytes
-rw-r--r--res/drawable-xhdpi/ic_spinner_outer_holo.pngbin0 -> 3416 bytes
-rw-r--r--res/drawable/progress_holo.xml34
-rw-r--r--res/layout/conversation_attachment_previews.xml14
-rw-r--r--res/values/colors.xml5
-rw-r--r--res/values/constants.xml6
-rw-r--r--res/values/dimen.xml2
-rw-r--r--src/com/android/mail/browse/ConversationItemView.java279
-rw-r--r--src/com/android/mail/browse/ConversationItemViewCoordinates.java13
-rw-r--r--src/com/android/mail/photomanager/AttachmentPreviewsManager.java22
-rw-r--r--src/com/android/mail/photomanager/PhotoManager.java62
-rw-r--r--src/com/android/mail/ui/DividedImageCanvas.java3
-rw-r--r--src/com/android/mail/ui/SwipeableListView.java4
20 files changed, 361 insertions, 83 deletions
diff --git a/res/drawable-hdpi/ic_attachment_load.png b/res/drawable-hdpi/ic_attachment_load.png
new file mode 100644
index 000000000..7b05b485d
--- /dev/null
+++ b/res/drawable-hdpi/ic_attachment_load.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_spinner_inner_holo.png b/res/drawable-hdpi/ic_spinner_inner_holo.png
new file mode 100644
index 000000000..e461e745e
--- /dev/null
+++ b/res/drawable-hdpi/ic_spinner_inner_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_spinner_outer_holo.png b/res/drawable-hdpi/ic_spinner_outer_holo.png
new file mode 100644
index 000000000..d495aa804
--- /dev/null
+++ b/res/drawable-hdpi/ic_spinner_outer_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_attachment_load.png b/res/drawable-mdpi/ic_attachment_load.png
new file mode 100644
index 000000000..752149dde
--- /dev/null
+++ b/res/drawable-mdpi/ic_attachment_load.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_spinner_inner_holo.png b/res/drawable-mdpi/ic_spinner_inner_holo.png
new file mode 100644
index 000000000..0c0698146
--- /dev/null
+++ b/res/drawable-mdpi/ic_spinner_inner_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_spinner_outer_holo.png b/res/drawable-mdpi/ic_spinner_outer_holo.png
new file mode 100644
index 000000000..46061dbb3
--- /dev/null
+++ b/res/drawable-mdpi/ic_spinner_outer_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_attachment_load.png b/res/drawable-xhdpi/ic_attachment_load.png
new file mode 100644
index 000000000..92ed99b50
--- /dev/null
+++ b/res/drawable-xhdpi/ic_attachment_load.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_spinner_inner_holo.png b/res/drawable-xhdpi/ic_spinner_inner_holo.png
new file mode 100644
index 000000000..273e8e8b2
--- /dev/null
+++ b/res/drawable-xhdpi/ic_spinner_inner_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_spinner_outer_holo.png b/res/drawable-xhdpi/ic_spinner_outer_holo.png
new file mode 100644
index 000000000..568e9eb7b
--- /dev/null
+++ b/res/drawable-xhdpi/ic_spinner_outer_holo.png
Binary files differ
diff --git a/res/drawable/progress_holo.xml b/res/drawable/progress_holo.xml
new file mode 100644
index 000000000..d4ad73330
--- /dev/null
+++ b/res/drawable/progress_holo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <rotate
+ android:drawable="@drawable/ic_spinner_outer_holo"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fromDegrees="0"
+ android:toDegrees="1080" />
+ </item>
+ <item>
+ <rotate
+ android:drawable="@drawable/ic_spinner_inner_holo"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fromDegrees="720"
+ android:toDegrees="0" />
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/res/layout/conversation_attachment_previews.xml b/res/layout/conversation_attachment_previews.xml
index eb7ce2591..7887e49b3 100644
--- a/res/layout/conversation_attachment_previews.xml
+++ b/res/layout/conversation_attachment_previews.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
+<!-- The height is set programmatically set in CIVC -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/attachment_previews"
android:layout_width="match_parent"
@@ -8,7 +9,7 @@
android:layout_marginLeft="@dimen/attachment_preview_margin_side"
android:layout_marginRight="@dimen/attachment_preview_margin_side"
android:visibility="gone" >
- <!--todo:markwei get font color, typeface, and size from channah-->
+ <!-- Use dips for textSize since we want the badge to be a fixed size. -->
<TextView
android:id="@+id/ap_overflow"
android:layout_width="@dimen/ap_overflow_count_diameter"
@@ -18,12 +19,17 @@
android:layout_gravity="bottom|right"
android:includeFontPadding="false"
android:textStyle="bold"
- android:textSize="12sp"/>
- <!--todo:markwei get actual spinner asset from channah-->
+ android:textSize="10dp"/>
+ <ImageView
+ android:id="@+id/ap_placeholder"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:src="@drawable/ic_attachment_load" />
<ImageView
android:id="@+id/ap_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:src="@drawable/spinner_holo" />
+ android:src="@drawable/ic_spinner_inner_holo" />
</FrameLayout> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 5af4a3d84..3f6ccffb0 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -32,9 +32,8 @@
<color name="date_text_color">@color/dark_gray_text_color</color>
<color name="message_info_text_color">@color/gray_text_color</color>
<color name="subject_text_color">#333333</color>
- <!--todo:markwei get overflow badge and count color from channah-->
- <color name="ap_overflow_badge_color">#aaeeeeee</color>
- <color name="ap_overflow_text_color">@android:color/tertiary_text_light</color>
+ <color name="ap_overflow_badge_color">#eeeeeeee</color>
+ <color name="ap_overflow_text_color">#ff4f4c4c</color>
<!-- a 'checked' item is in the conversation selection set. also the 'pressed' color. -->
<!-- this is holo_blue_light @ 20% opacity -->
<color name="checked_item_background_color">#cfe9f3</color>
diff --git a/res/values/constants.xml b/res/values/constants.xml
index 517ae8dd3..4cf939934 100644
--- a/res/values/constants.xml
+++ b/res/values/constants.xml
@@ -115,6 +115,12 @@
<!-- Number of menu items to hide from the ActionBar by subtracting from actionbar_max_items in non-cab mode -->
<integer name="actionbar_hidden_non_cab_items_no_physical_button">1</integer>
+ <!-- Duration of progress bar animation for attachment previews -->
+ <integer name="ap_progress_animation_duration">4000</integer>
+ <!-- Duration of placeholder pulse animation for attachment previews -->
+ <integer name="ap_placeholder_animation_duration">2000</integer>
+ <!-- Delay before showing progress bar animations for attachment previews that are loading -->
+ <integer name="ap_progress_animation_delay">2000</integer>
<!-- Max overflow count to show for attachment previews -->
<integer name="ap_overflow_max_count">99</integer>
</resources>
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 22fca7502..d4e337212 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -127,9 +127,7 @@
<dimen name="attachment_preview_margin_bottom">4dp</dimen>
<dimen name="attachment_preview_margin_bottom_wide">8dp</dimen>
- <!--todo:markwei get the diameter from channah-->
<dimen name="ap_overflow_count_diameter">20dp</dimen>
- <!--todo:markwei channah wanted 8dp but only 4dp fits read previews-->
<dimen name="ap_margin_side">4dp</dimen>
<dimen name="folder_minimum_width">48dip</dimen>
diff --git a/src/com/android/mail/browse/ConversationItemView.java b/src/com/android/mail/browse/ConversationItemView.java
index a56a95b8b..c6da7abc0 100644
--- a/src/com/android/mail/browse/ConversationItemView.java
+++ b/src/com/android/mail/browse/ConversationItemView.java
@@ -36,6 +36,7 @@ import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.SystemClock;
import android.text.Layout.Alignment;
import android.text.Spannable;
import android.text.SpannableString;
@@ -57,8 +58,11 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
+import android.widget.AbsListView.OnScrollListener;
import android.widget.TextView;
import com.android.mail.R;
@@ -75,6 +79,7 @@ import com.android.mail.photomanager.AttachmentPreviewsManager.AttachmentPreview
import com.android.mail.photomanager.ContactPhotoManager;
import com.android.mail.photomanager.ContactPhotoManager.ContactIdentifier;
import com.android.mail.photomanager.AttachmentPreviewsManager.AttachmentPreviewIdentifier;
+import com.android.mail.photomanager.PhotoManager;
import com.android.mail.photomanager.PhotoManager.PhotoIdentifier;
import com.android.mail.providers.Address;
import com.android.mail.providers.Attachment;
@@ -135,7 +140,8 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
private static Bitmap STATE_CALENDAR_INVITE;
private static Bitmap VISIBLE_CONVERSATION_CARET;
private static Drawable RIGHT_EDGE_TABLET;
- private static Bitmap PROGRESS_BAR;
+ private static Bitmap PLACEHOLDER;
+ private static Drawable PROGRESS_BAR;
private static String sSendersSplitToken;
private static String sElidedPaddingToken;
@@ -155,8 +161,10 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
private static int sShrinkAnimationDuration;
private static int sSlideAnimationDuration;
private static int sAnimatingBackgroundColor;
- // todo:markwei get duration from channah
private static int sProgressAnimationDuration;
+ private static float sPlaceholderAnimationDurationRatio;
+ private static int sProgressAnimationDelay;
+ private static Interpolator sPulseAnimationInterpolator;
private static int sOverflowCountMax;
// Static paints.
@@ -228,8 +236,12 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
* this animator does not remove the progress bars.
*/
private final ObjectAnimator mProgressAnimator;
+ private long mProgressAnimatorCancelledTime;
+ /** Range from 0.0f to 1.0f. */
private float mAnimatedProgressFraction;
- private boolean[] mImagesLoaded = new boolean[0];
+ private int[] mImagesLoaded = new int[0];
+ private boolean mShowProgressBar;
+ private Runnable mSetShowProgressBarRunnable;
private static final boolean CONVLIST_ATTACHMENT_PREVIEWS_ENABLED = true;
static {
@@ -237,18 +249,24 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
sFoldersPaint.setAntiAlias(true);
}
- public static void setPhotoManagersPaused(boolean shouldPause) {
+ public static void setScrollStateChanged(final int scrollState) {
if (sContactPhotoManager == null) {
return;
}
+ final boolean scrolling = scrollState != OnScrollListener.SCROLL_STATE_IDLE;
+ final boolean flinging = scrollState == OnScrollListener.SCROLL_STATE_FLING;
- if (shouldPause) {
- sContactPhotoManager.pause();
+ if (scrolling) {
sAttachmentPreviewsManager.pause();
} else {
- sContactPhotoManager.resume();
sAttachmentPreviewsManager.resume();
}
+
+ if (flinging) {
+ sContactPhotoManager.pause();
+ } else {
+ sContactPhotoManager.resume();
+ }
}
/**
@@ -429,8 +447,8 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
VISIBLE_CONVERSATION_CARET = BitmapFactory.decodeResource(res,
R.drawable.ic_carrot_holo);
RIGHT_EDGE_TABLET = res.getDrawable(R.drawable.list_edge_tablet);
-// todo:markwei get actual spinner asset from channah
- PROGRESS_BAR = BitmapFactory.decodeResource(res, drawable.spinner_holo);
+ PLACEHOLDER = BitmapFactory.decodeResource(res, drawable.ic_attachment_load);
+ PROGRESS_BAR = res.getDrawable(drawable.progress_holo);
// Initialize colors.
sActivatedTextColor = res.getColor(R.color.senders_text_color_read);
@@ -462,8 +480,13 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
sFoldersLeftPadding = res.getDimensionPixelOffset(R.dimen.folders_left_padding);
sContactPhotoManager = ContactPhotoManager.createContactPhotoManager(context);
sAttachmentPreviewsManager = new AttachmentPreviewsManager(context);
- // todo:markwei get animation duration from channah
- sProgressAnimationDuration = 1000;
+ sProgressAnimationDuration = res.getInteger(integer.ap_progress_animation_duration);
+ final int placeholderAnimationDuration = res
+ .getInteger(integer.ap_placeholder_animation_duration);
+ sPlaceholderAnimationDurationRatio = sProgressAnimationDuration
+ / placeholderAnimationDuration;
+ sProgressAnimationDelay = res.getInteger(integer.ap_progress_animation_delay);
+ sPulseAnimationInterpolator = new AccelerateDecelerateInterpolator();
sOverflowCountMax = res.getInteger(integer.ap_overflow_max_count);
}
@@ -503,6 +526,14 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
});
mProgressAnimator = createProgressAnimator();
+ mSetShowProgressBarRunnable = new Runnable() {
+ @Override
+ public void run() {
+ LogUtils.v(LOG_TAG, "progress bar: >>> set to true");
+ // It's OK to set this field to true when the status is no longer LOADING.
+ mShowProgressBar = true;
+ }
+ };
Utils.traceEndSection();
}
@@ -518,6 +549,7 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
private void bind(ConversationItemViewModel header, ControllableActivity activity,
ConversationSelectionSet set, Folder folder, int checkboxOrSenderImage,
boolean swipeEnabled, boolean priorityArrowEnabled, AnimatedAdapter adapter) {
+ boolean attachmentPreviewsChanged = false;
if (mHeader != null) {
// If this was previously bound to a different conversation, remove any contact photo
// manager requests.
@@ -541,6 +573,7 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
!= mHeader.conversation.attachmentPreviewsCount
|| !header.conversation.getAttachmentPreviewUris()
.equals(mHeader.conversation.getAttachmentPreviewUris())) {
+ attachmentPreviewsChanged = true;
ArrayList<String> divisionIds = mAttachmentPreviewsCanvas.getDivisionIds();
if (divisionIds != null) {
mAttachmentPreviewsCanvas.reset();
@@ -565,7 +598,10 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
mStarEnabled = folder != null && !folder.isTrash();
mSwipeEnabled = swipeEnabled;
mAdapter = adapter;
- mImagesLoaded = new boolean[mHeader.conversation.getAttachmentPreviewUris().size()];
+ final int attachmentPreviewsSize = mHeader.conversation.getAttachmentPreviewUris().size();
+ if (attachmentPreviewsChanged || mImagesLoaded.length != attachmentPreviewsSize) {
+ mImagesLoaded = new int[attachmentPreviewsSize];
+ }
if (checkboxOrSenderImage == ConversationListIcon.SENDER_IMAGE) {
mGadgetMode = ConversationItemViewCoordinates.GADGET_CONTACT_PHOTO;
@@ -878,8 +914,6 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
Utils.traceBeginSection("Setup load attachment previews");
LogUtils.d(LOG_TAG,
- "loadAttachmentPreviews: ###############################################");
- LogUtils.d(LOG_TAG,
"loadAttachmentPreviews: Loading attachment previews for conversation %s",
mHeader.conversation);
@@ -897,7 +931,7 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
final String uri = attachmentUris.get(i);
// Find the rendition to load based on availability.
- LogUtils.d(LOG_TAG, "loadAttachmentPreviews: state [BEST, SIMPLE] is [%s, %s] for %s ",
+ LogUtils.v(LOG_TAG, "loadAttachmentPreviews: state [BEST, SIMPLE] is [%s, %s] for %s ",
Attachment.getPreviewState(previewStates, i, AttachmentRendition.BEST),
Attachment.getPreviewState(previewStates, i, AttachmentRendition.SIMPLE),
uri);
@@ -927,59 +961,132 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
// Second pass: Find the dimensions to load and start the load request
final ImageCanvas.Dimensions canvasDimens = new ImageCanvas.Dimensions();
for (int i = 0; i < displayCount; i++) {
+ Utils.traceBeginSection("finding dimensions");
final PhotoIdentifier photoIdentifier = ids.get(i);
final Object key = keys.get(i);
mAttachmentPreviewsCanvas.getDesiredDimensions(key, canvasDimens);
- if (i < mImagesLoaded.length) {
- // We want to show default progress image
- mImagesLoaded[i] = false;
- if (!mProgressAnimator.isStarted()) {
- LogUtils.d(LOG_TAG, "progress animator: >> started");
- mProgressAnimator.setCurrentPlayTime(
- (long) (sProgressAnimationDuration * mAnimatedProgressFraction));
- mProgressAnimator.start();
+ Utils.traceEndSection();
+
+ Utils.traceBeginSection("start animator");
+ // We want to show default progress image
+ setImageLoaded(i, PhotoManager.STATUS_NOT_LOADED);
+ if (!mProgressAnimator.isStarted()) {
+ LogUtils.v(LOG_TAG, "progress animator: >> started");
+ // Reduce progress bar stutter caused by reset()/bind() being called multiple
+ // times.
+ final long time = SystemClock.uptimeMillis();
+ final long dt = time - mProgressAnimatorCancelledTime;
+ float passedFraction = 0;
+ if (mProgressAnimatorCancelledTime != 0 && dt > 0) {
+ mProgressAnimatorCancelledTime = 0;
+ passedFraction = (float) dt / sProgressAnimationDuration % 1.0f;
+ LogUtils.v(LOG_TAG, "progress animator: correction for dt %d, fraction %f",
+ dt, passedFraction);
}
+ mProgressAnimator.start();
+ // Wow.. this must be called after start().
+ mProgressAnimator.setCurrentPlayTime((long) (sProgressAnimationDuration * (
+ (mAnimatedProgressFraction + passedFraction) % 1.0f)));
}
+ Utils.traceEndSection();
+
+ Utils.traceBeginSection("start load");
LogUtils.d(LOG_TAG, "loadAttachmentPreviews: start loading %s", photoIdentifier);
sAttachmentPreviewsManager
.loadThumbnail(photoIdentifier, mAttachmentPreviewsCanvas, canvasDimens, this);
+ Utils.traceEndSection();
}
+
Utils.traceEndSection();
}
@Override
- public void onImageDrawn(Object key, boolean success) {
- Utils.traceBeginSection("on image drawn");
- String uri = AttachmentPreviewsManager.transformKeyToUri(key);
- int index = mHeader.conversation.getAttachmentPreviewUris().indexOf(uri);
-
- if (index < 0 || index >= mImagesLoaded.length) {
- Utils.traceEndSection();
+ public void onImageDrawn(final Object key, final boolean success) {
+ if (mHeader == null || mHeader.conversation == null) {
return;
}
+ Utils.traceBeginSection("on image drawn");
+ final String uri = AttachmentPreviewsManager.transformKeyToUri(key);
+ final int index = mHeader.conversation.getAttachmentPreviewUris().indexOf(uri);
- LogUtils.d(LOG_TAG,
+ LogUtils.v(LOG_TAG,
"loadAttachmentPreviews: <= onImageDrawn callback [%b] on index %d for %s", success,
index, key);
// We want to hide the spinning progress bar when we draw something.
- mImagesLoaded[index] = success;
+ setImageLoaded(index,
+ success ? PhotoManager.STATUS_LOADED : PhotoManager.STATUS_NOT_LOADED);
if (mProgressAnimator.isStarted() && areAllImagesLoaded()) {
- LogUtils.d(LOG_TAG, "progress animator: << stopped");
+ LogUtils.v(LOG_TAG, "progress animator: << stopped");
mProgressAnimator.cancel();
}
Utils.traceEndSection();
}
+ @Override
+ public void onImageLoadStarted(final Object key) {
+ if (mHeader == null || mHeader.conversation == null) {
+ return;
+ }
+ final String uri = AttachmentPreviewsManager.transformKeyToUri(key);
+ final int index = mHeader.conversation.getAttachmentPreviewUris().indexOf(uri);
+
+ LogUtils.v(LOG_TAG,
+ "loadAttachmentPreviews: <= onImageLoadStarted callback on index %d for %s", index,
+ key);
+ setImageLoaded(index, PhotoManager.STATUS_LOADING);
+ }
+
private boolean areAllImagesLoaded() {
for (int i = 0; i < mImagesLoaded.length; i++) {
- if (!mImagesLoaded[i]) {
+ if (mImagesLoaded[i] != PhotoManager.STATUS_LOADED) {
return false;
}
}
return true;
}
+ /**
+ * Update the #mImagesLoaded state array with special logic.
+ * @param index Which attachment preview's state to update.
+ * @param status What the new state is.
+ */
+ private void setImageLoaded(final int index, final int status) {
+ if (index < 0 || index >= mImagesLoaded.length) {
+ return;
+ }
+ final int prevStatus = mImagesLoaded[index];
+ switch (status) {
+ case PhotoManager.STATUS_NOT_LOADED:
+ // Cannot transition directly from LOADING to NOT_LOADED.
+ if (prevStatus != PhotoManager.STATUS_LOADING) {
+ mImagesLoaded[index] = status;
+ }
+ break;
+ case PhotoManager.STATUS_LOADING:
+ // All other statuses must be set to not loading.
+ for (int i = 0; i < mImagesLoaded.length; i++) {
+ if (i != index && mImagesLoaded[i] == PhotoManager.STATUS_LOADING) {
+ mImagesLoaded[i] = PhotoManager.STATUS_NOT_LOADED;
+ }
+ }
+ mImagesLoaded[index] = status;
+
+ if (prevStatus != PhotoManager.STATUS_LOADING) {
+ // Progress bar should only be shown after a delay
+ LogUtils.v(LOG_TAG, "progress bar: <<< set to false");
+ mShowProgressBar = false;
+ LogUtils.v(LOG_TAG, "progress bar: === start delay");
+ removeCallbacks(mSetShowProgressBarRunnable);
+ postDelayed(mSetShowProgressBarRunnable, sProgressAnimationDelay);
+ }
+ break;
+ case PhotoManager.STATUS_LOADED:
+ mImagesLoaded[index] = status;
+ break;
+ }
+ }
+
private static int makeExactSpecForSize(int size) {
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
@@ -1421,8 +1528,7 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
// Overflow badge and count
if (getOverflowCountVisible() && areAllImagesLoaded()) {
- float radius = mCoordinates.overflowDiameter / 2;
- // todo:markwei get color of overflow badge from channah
+ final float radius = mCoordinates.overflowDiameter / 2;
sPaint.setColor(sOverflowBadgeColor);
canvas.drawCircle(mCoordinates.overflowXEnd - radius,
mCoordinates.overflowYEnd - radius, radius, sPaint);
@@ -1435,12 +1541,35 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
// Progress bar
if (mProgressAnimator.isRunning()) {
+ // Fade from 55 -> 255 -> 55. Each cycle lasts for #sProgressAnimationDuration secs.
+ final int maxAlpha = 255, minAlpha = 55;
+ final int range = maxAlpha - minAlpha;
+ // We want the placeholder to pulse at a different rate from the progressbar to
+ // spin.
+ final float placeholderAnimFraction = mAnimatedProgressFraction
+ * sPlaceholderAnimationDurationRatio;
+ // During the time that placeholderAnimFraction takes to go from 0 to 1, we
+ // want to go all the way to #maxAlpha and back down to #minAlpha. So from 0 to 0.5,
+ // we increase #modifiedProgress from 0 to 1, while from 0.5 to 1 we decrease
+ // accordingly from 1 to 0. Math.
+ final float modifiedProgress = -2 * Math.abs(placeholderAnimFraction - 0.5f) + 1;
+ // Make it feel like a heart beat.
+ final float interpolatedProgress = sPulseAnimationInterpolator
+ .getInterpolation(modifiedProgress);
+ // More math.
+ final int alpha = (int) (interpolatedProgress * range + minAlpha);
+ sPaint.setAlpha(alpha);
+
final int count = mImagesLoaded.length;
for (int i = 0; i < count; i++) {
- if (!mImagesLoaded[i]) {
+ if (mShowProgressBar && mImagesLoaded[i] == PhotoManager.STATUS_LOADING) {
+ // status is LOADING and enough time has passed
canvas.save();
drawProgressBar(canvas, i, count);
canvas.restore();
+ } else if (mImagesLoaded[i] != PhotoManager.STATUS_LOADED) {
+ // status is either NOT_LOADED or LOADING
+ drawPlaceholder(canvas, i, count);
}
}
}
@@ -1484,6 +1613,21 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
}
/**
+ * Draws the specified placeholder on the canvas.
+ * @param canvas The canvas to draw on.
+ * @param index If drawing multiple progress bars, this determines which one we are drawing.
+ * @param total Whether we are drawing multiple progress bars.
+ */
+ private void drawPlaceholder(Canvas canvas, int index, int total) {
+ int placeholderX = getPlaceholderX(index, total);
+ if (placeholderX == -1) {
+ return;
+ }
+
+ canvas.drawBitmap(PLACEHOLDER, placeholderX, mCoordinates.placeholderY, sPaint);
+ }
+
+ /**
* Draws the specified progress bar on the canvas.
* @param canvas The canvas to draw on.
* @param index If drawing multiple progress bars, this determines which one we are drawing.
@@ -1495,18 +1639,19 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
return;
}
- // We want to rotate counter-clockwise, because that's the direction the asset faces
- canvas.rotate(360 - mAnimatedProgressFraction * 360,
- progressBarX + mCoordinates.progressBarWidth / 2,
- mCoordinates.progressBarY + mCoordinates.progressBarHeight / 2);
-
- canvas.drawBitmap(PROGRESS_BAR, progressBarX, mCoordinates.progressBarY, null);
+ // Set the level from 0 to 10000 to animate the Drawable.
+ PROGRESS_BAR.setLevel((int) (mAnimatedProgressFraction * 10000));
+ // canvas.translate() for Bitmaps, setBounds() for Drawables.
+ PROGRESS_BAR.setBounds(progressBarX, mCoordinates.progressBarY,
+ progressBarX + mCoordinates.progressBarWidth,
+ mCoordinates.progressBarY + mCoordinates.progressBarHeight);
+ PROGRESS_BAR.draw(canvas);
}
/**
* @see com.android.mail.browse.ConversationItemView#drawProgressBar
*/
- private void invalidateProgressBar(int index, int total) {
+ private void invalidatePlaceholderAndProgressBar(int index, int total) {
int progressBarX = getProgressBarX(index, total);
if (progressBarX == -1) {
return;
@@ -1515,6 +1660,25 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
invalidate(progressBarX, mCoordinates.progressBarY,
progressBarX + mCoordinates.progressBarWidth,
mCoordinates.progressBarY + mCoordinates.progressBarHeight);
+
+ int placeholderX = getPlaceholderX(index, total);
+ if (placeholderX == -1) {
+ return;
+ }
+
+ invalidate(placeholderX, mCoordinates.placeholderY,
+ placeholderX + mCoordinates.placeholderWidth,
+ mCoordinates.placeholderY + mCoordinates.placeholderHeight);
+ }
+
+ private int getPlaceholderX(int index, int total) {
+ if (mCoordinates == null) {
+ return -1;
+ }
+ int sectionWidth = mCoordinates.attachmentPreviewsWidth / total;
+ int sectionOffset = index * sectionWidth;
+ return mCoordinates.attachmentPreviewsX + sectionOffset + sectionWidth / 2
+ - mCoordinates.placeholderWidth / 2;
}
private int getProgressBarX(int index, int total) {
@@ -1800,9 +1964,8 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
setAlpha(1f);
setTranslationX(0f);
mAnimatedHeightFraction = 1.0f;
- LogUtils.d(LOG_TAG, "progress animator: cancelling after %dms", sProgressAnimationDuration);
if (mProgressAnimator.isStarted()) {
- LogUtils.d(LOG_TAG, "progress animator: << stopped");
+ LogUtils.v(LOG_TAG, "progress animator: << stopped");
mProgressAnimator.cancel();
}
Utils.traceEndSection();
@@ -1899,26 +2062,28 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
}
private ObjectAnimator createProgressAnimator() {
- ObjectAnimator animator = ObjectAnimator.ofFloat(this, "animatedProgressFraction", 0f, 1.0f)
- .setDuration(sProgressAnimationDuration);
+ final ObjectAnimator animator = ObjectAnimator
+ .ofFloat(this, "animatedProgressFraction", 0f, 1.0f).setDuration(
+ sProgressAnimationDuration);
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(ObjectAnimator.INFINITE);
animator.setRepeatMode(ObjectAnimator.RESTART);
animator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationEnd(final Animator animation) {
invalidateAll();
}
@Override
- public void onAnimationCancel(Animator animation) {
+ public void onAnimationCancel(final Animator animation) {
invalidateAll();
+ mProgressAnimatorCancelledTime = SystemClock.uptimeMillis();
}
private void invalidateAll() {
- int count = mHeader.conversation.getAttachmentPreviewUris().size();
+ final int count = mHeader.conversation.getAttachmentPreviewUris().size();
for (int i = 0; i < count; i++) {
- invalidateProgressBar(i, count);
+ invalidatePlaceholderAndProgressBar(i, count);
}
}
});
@@ -1926,12 +2091,16 @@ public class ConversationItemView extends View implements SwipeableItemView, Tog
}
// Used by animator
- public void setAnimatedProgressFraction(float fraction) {
+ public void setAnimatedProgressFraction(final float fraction) {
+ // ObjectAnimator.cancel() sets the field to 0.0f.
+ if (fraction == 0.0f) {
+ return;
+ }
mAnimatedProgressFraction = fraction;
final int count = mImagesLoaded.length;
for (int i = 0; i < count; i++) {
- if (!mImagesLoaded[i]) {
- invalidateProgressBar(i, count);
+ if (mImagesLoaded[i] != PhotoManager.STATUS_LOADED) {
+ invalidatePlaceholderAndProgressBar(i, count);
}
}
}
diff --git a/src/com/android/mail/browse/ConversationItemViewCoordinates.java b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
index 34b5596b3..543f63657 100644
--- a/src/com/android/mail/browse/ConversationItemViewCoordinates.java
+++ b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
@@ -250,6 +250,10 @@ public class ConversationItemViewCoordinates {
final float overflowFontSize;
final Typeface overflowTypeface;
+ // Attachment previews placeholder
+ final int placeholderY;
+ final int placeholderWidth;
+ final int placeholderHeight;
// Attachment previews progress bar
final int progressBarY;
final int progressBarWidth;
@@ -483,6 +487,12 @@ public class ConversationItemViewCoordinates {
overflowFontSize = overflow.getTextSize();
overflowTypeface = overflow.getTypeface();
+ final View placeholder = view.findViewById(id.ap_placeholder);
+ placeholderWidth = placeholder.getWidth();
+ placeholderHeight = placeholder.getHeight();
+ placeholderY = attachmentPreviewsY + attachmentPreviewsHeight / 2
+ - placeholderHeight / 2;
+
final View progressBar = view.findViewById(id.ap_progress_bar);
progressBarWidth = progressBar.getWidth();
progressBarHeight = progressBar.getHeight();
@@ -498,6 +508,9 @@ public class ConversationItemViewCoordinates {
overflowDiameter = 0;
overflowFontSize = 0;
overflowTypeface = null;
+ placeholderY = 0;
+ placeholderWidth = 0;
+ placeholderHeight = 0;
progressBarY = 0;
progressBarWidth = 0;
progressBarHeight = 0;
diff --git a/src/com/android/mail/photomanager/AttachmentPreviewsManager.java b/src/com/android/mail/photomanager/AttachmentPreviewsManager.java
index dc584f34e..10149e973 100644
--- a/src/com/android/mail/photomanager/AttachmentPreviewsManager.java
+++ b/src/com/android/mail/photomanager/AttachmentPreviewsManager.java
@@ -85,6 +85,18 @@ public class AttachmentPreviewsManager extends PhotoManager {
}
@Override
+ protected void onImageLoadStarted(final Request request) {
+ if (request == null) {
+ return;
+ }
+ final Object key = request.getKey();
+ if (mCallbacks.containsKey(key)) {
+ AttachmentPreviewsManagerCallback callback = mCallbacks.get(key);
+ callback.onImageLoadStarted(request.getKey());
+ }
+ }
+
+ @Override
protected boolean isSizeCompatible(int prevWidth, int prevHeight, int newWidth, int newHeight) {
float ratio = (float) newWidth / prevWidth;
boolean previousRequestSmaller = newWidth > prevWidth
@@ -235,7 +247,7 @@ public class AttachmentPreviewsManager extends PhotoManager {
}
Attachment attachment = null;
try {
- LogUtils.d(TAG, "AttachmentPreviewsManager: found %d attachments for uri %s",
+ LogUtils.v(TAG, "AttachmentPreviewsManager: found %d attachments for uri %s",
cursor.getCount(), uri);
if (cursor.moveToFirst()) {
attachment = new Attachment(cursor);
@@ -245,7 +257,7 @@ public class AttachmentPreviewsManager extends PhotoManager {
}
if (attachment == null) {
- LogUtils.d(TAG, "AttachmentPreviewsManager: attachment not found for uri %s",
+ LogUtils.w(TAG, "AttachmentPreviewsManager: attachment not found for uri %s",
uri);
Utils.traceEndSection();
continue;
@@ -258,14 +270,14 @@ public class AttachmentPreviewsManager extends PhotoManager {
} else if (id.rendition == AttachmentRendition.SIMPLE) {
contentUri = attachment.thumbnailUri;
} else {
- LogUtils.d(TAG,
+ LogUtils.w(TAG,
"AttachmentPreviewsManager: Cannot load rendition %d for uri %s",
id.rendition, uri);
Utils.traceEndSection();
continue;
}
- LogUtils.d(TAG, "AttachmentPreviewsManager: attachments has contentUri %s",
+ LogUtils.v(TAG, "AttachmentPreviewsManager: attachments has contentUri %s",
contentUri);
final InputStreamFactory factory = new InputStreamFactory() {
@Override
@@ -348,5 +360,7 @@ public class AttachmentPreviewsManager extends PhotoManager {
public interface AttachmentPreviewsManagerCallback {
public void onImageDrawn(Object key, boolean success);
+
+ public void onImageLoadStarted(Object key);
}
}
diff --git a/src/com/android/mail/photomanager/PhotoManager.java b/src/com/android/mail/photomanager/PhotoManager.java
index 57d2fa136..66c1058b2 100644
--- a/src/com/android/mail/photomanager/PhotoManager.java
+++ b/src/com/android/mail/photomanager/PhotoManager.java
@@ -47,6 +47,9 @@ import java.util.concurrent.atomic.AtomicInteger;
* Asynchronously loads photos and maintains a cache of photos
*/
public abstract class PhotoManager implements ComponentCallbacks2, Callback {
+ public static final int STATUS_NOT_LOADED = 0;
+ public static final int STATUS_LOADING = 1;
+ public static final int STATUS_LOADED = 2;
/**
* Get the default image provider that draws while the photo is being
* loaded.
@@ -64,12 +67,20 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
protected abstract PhotoLoaderThread getLoaderThread(ContentResolver contentResolver);
/**
- * Subclasses can implement this method to alert callbacks of the images' loading progress.
+ * Subclasses can implement this method to alert callbacks that images finished loading.
* @param request The original request made.
* @param success True if we successfully loaded the image from cache. False if we fell back
* to the default image.
*/
- protected void onImageDrawn(Request request, boolean success) {
+ protected void onImageDrawn(final Request request, final boolean success) {
+ // Subclasses can choose to do something about this
+ }
+
+ /**
+ * Subclasses can implement this method to alert callbacks that images started loading.
+ * @param request The original request made.
+ */
+ protected void onImageLoadStarted(final Request request) {
// Subclasses can choose to do something about this
}
@@ -108,6 +119,11 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
*/
private static final int MESSAGE_PHOTOS_LOADED = 2;
+ /**
+ * Type of message sent by the loader thread to indicate that
+ */
+ private static final int MESSAGE_PHOTO_LOADING = 3;
+
public interface DefaultImageProvider {
/**
* Applies the default avatar to the DividedImageView. Extent is an
@@ -154,6 +170,7 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
}
}
+ // todo:ath caches should be member vars
/**
* An LRU cache for bitmap holders. The cache contains bytes for photos just
* as they come from the database. Each holder has a soft reference to the
@@ -326,13 +343,14 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
/**
* Checks if the photo is present in cache. If so, sets the photo on the view.
*
- * @param request Determines which image to load from cache.
+ * @param request Determines which image to load from cache.
* @param afterLoaderThreadFinished Pass true if calling after the LoaderThread has run. Pass
* false if the Loader Thread hasn't made any attempts to
* load images yet.
* @return false if the photo needs to be (re)loaded from the provider.
*/
- private boolean loadCachedPhoto(Request request, boolean afterLoaderThreadFinished) {
+ private boolean loadCachedPhoto(final Request request,
+ final boolean afterLoaderThreadFinished) {
Utils.traceBeginSection("Load cached photo");
final Bitmap cached = getCachedPhoto(request.bitmapKey);
if (cached != null) {
@@ -345,8 +363,8 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
Thread.currentThread());
}
if (request.getView().getGeneration() == request.viewGeneration) {
- onImageDrawn(request, true);
request.getView().drawImage(cached, request.getKey());
+ onImageDrawn(request, true);
}
Utils.traceEndSection();
return true;
@@ -369,8 +387,8 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
Thread.currentThread());
}
if (request.getView().getGeneration() == request.viewGeneration) {
- onImageDrawn(request, true);
request.getView().drawImage(cachedReplacement, request.getKey());
+ onImageDrawn(request, true);
}
Utils.traceEndSection();
return false;
@@ -405,6 +423,7 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
* Temporarily stops loading photos from the database.
*/
public void pause() {
+ LogUtils.d(TAG, "%s paused.", getClass().getName());
mPaused = true;
}
@@ -412,6 +431,7 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
* Resumes loading photos from the database.
*/
public void resume() {
+ LogUtils.d(TAG, "%s resumed.", getClass().getName());
mPaused = false;
if (DEBUG) dumpStats();
if (!mPendingRequests.isEmpty()) {
@@ -436,7 +456,7 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
* Processes requests on the main thread.
*/
@Override
- public boolean handleMessage(Message msg) {
+ public boolean handleMessage(final Message msg) {
switch (msg.what) {
case MESSAGE_REQUEST_LOADING: {
mLoadingRequested = false;
@@ -454,6 +474,15 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
if (DEBUG) dumpStats();
return true;
}
+
+ case MESSAGE_PHOTO_LOADING: {
+ if (!mPaused) {
+ final int hashcode = msg.arg1;
+ final Request request = mPendingRequests.get(hashcode);
+ onImageLoadStarted(request);
+ }
+ return true;
+ }
}
return false;
}
@@ -468,7 +497,10 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
for (Integer hash : mPendingRequests.keySet()) {
Request request = mPendingRequests.get(hash);
boolean loaded = loadCachedPhoto(request, true);
- if (loaded) {
+ // Request can go through multiple attempts if the LoaderThread fails to load any
+ // images for it, or if the images it loads are evicted from the cache before we
+ // could access them in the main thread.
+ if (loaded || request.attempts > 2) {
toRemove.add(hash);
}
}
@@ -476,9 +508,6 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
mPendingRequests.remove(key);
}
- // TODO: this already seems to happen when calling loadCachedPhoto
- //softenCache();
-
if (!mPendingRequests.isEmpty()) {
LogUtils.d(TAG, "Finished loading batch. %d still have to be loaded.",
mPendingRequests.size());
@@ -695,6 +724,11 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
loadRequests.add(request);
decodeRequests.add(request);
batchCount++;
+
+ final Message msg = Message.obtain();
+ msg.what = MESSAGE_PHOTO_LOADING;
+ msg.arg1 = request.hashCode();
+ mMainThreadHandler.sendMessage(msg);
} else {
// Even if the image load is already done, this particular decode configuration
// may not yet have run. Be sure to add it to the queue.
@@ -702,6 +736,7 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
decodeRequests.add(request);
}
}
+ request.attempts++;
if (maxBatchCount > 0 && batchCount >= maxBatchCount) {
break;
}
@@ -869,6 +904,7 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
private final ImageCanvas mView;
public final BitmapIdentifier bitmapKey;
public final int viewGeneration;
+ public int attempts;
private Request(PhotoIdentifier photoIdentifier, DefaultImageProvider defaultProvider,
ImageCanvas view, ImageCanvas.Dimensions dimensions) {
@@ -953,6 +989,10 @@ public abstract class PhotoManager implements ComponentCallbacks2, Callback {
@Override
public int compareTo(Request another) {
+ // Hold off on loading Requests which have failed before so it don't hold up others
+ if (attempts - another.attempts != 0) {
+ return attempts - another.attempts;
+ }
return mPhotoIdentifier.compareTo(another.mPhotoIdentifier);
}
}
diff --git a/src/com/android/mail/ui/DividedImageCanvas.java b/src/com/android/mail/ui/DividedImageCanvas.java
index e40ff12cf..2880ea4d3 100644
--- a/src/com/android/mail/ui/DividedImageCanvas.java
+++ b/src/com/android/mail/ui/DividedImageCanvas.java
@@ -157,6 +157,7 @@ public class DividedImageCanvas implements ImageCanvas {
// l t r b
sSrc.set(0, srcTop, b.getWidth(), srcBottom);
sDest.set(left, top, right, bottom);
+ mCanvas.drawRect(sDest, sClearPaint);
mCanvas.drawBitmap(b, sSrc, sDest, sPaint);
} else {
// clear
@@ -372,8 +373,6 @@ public class DividedImageCanvas implements ImageCanvas {
* Draw the contents of the DividedImageCanvas to the supplied canvas.
*/
public void draw(Canvas canvas) {
- // todo:markwei we can see the old image behind transparency regions. Should we also
- // "clear" the canvas? ath
if (mDividedBitmap != null && mBitmapValid) {
canvas.drawBitmap(mDividedBitmap, 0, 0, null);
}
diff --git a/src/com/android/mail/ui/SwipeableListView.java b/src/com/android/mail/ui/SwipeableListView.java
index 80cf6defc..24189fd7f 100644
--- a/src/com/android/mail/ui/SwipeableListView.java
+++ b/src/com/android/mail/ui/SwipeableListView.java
@@ -373,7 +373,7 @@ public class SwipeableListView extends ListView implements Callback, OnScrollLis
}
@Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
+ public void onScrollStateChanged(final AbsListView view, final int scrollState) {
mScrolling = scrollState != OnScrollListener.SCROLL_STATE_IDLE;
if (!mScrolling) {
@@ -387,7 +387,7 @@ public class SwipeableListView extends ListView implements Callback, OnScrollLis
}
if (SCROLL_PAUSE_ENABLE) {
- ConversationItemView.setPhotoManagersPaused(mScrolling);
+ ConversationItemView.setScrollStateChanged(scrollState);
}
}