lazier and smaller conversation list progress bars

Avoid inflating refresh ProgressBars until they are actually needed.
ProgressBar inflation was instantiating all the drawable bitmaps, which
were 87KB on xhdpi * 9 assets (yikes). This was contributing to
excessive GCs, which slowed down list instantiation when coming back
from conversation view.

Also shrink the assets by removing the transparent bottom padding.

Bug: 8910559
Change-Id: If7bf3bb7df87646571b8e3aa371807b9b68d4656
diff --git a/res/drawable-hdpi/progressbar_indeterminate_holo1.png b/res/drawable-hdpi/progressbar_indeterminate_holo1.png
index 4246d83..971ece7 100644
--- a/res/drawable-hdpi/progressbar_indeterminate_holo1.png
+++ b/res/drawable-hdpi/progressbar_indeterminate_holo1.png
Binary files differ
diff --git a/res/drawable-hdpi/progressbar_indeterminate_holo2.png b/res/drawable-hdpi/progressbar_indeterminate_holo2.png
index 29eb64e..2089de3 100644
--- a/res/drawable-hdpi/progressbar_indeterminate_holo2.png
+++ b/res/drawable-hdpi/progressbar_indeterminate_holo2.png
Binary files differ
diff --git a/res/drawable-hdpi/progressbar_indeterminate_holo3.png b/res/drawable-hdpi/progressbar_indeterminate_holo3.png
index 3b51ddc..b6d0fc2 100644
--- a/res/drawable-hdpi/progressbar_indeterminate_holo3.png
+++ b/res/drawable-hdpi/progressbar_indeterminate_holo3.png
Binary files differ
diff --git a/res/drawable-hdpi/progressbar_indeterminate_holo4.png b/res/drawable-hdpi/progressbar_indeterminate_holo4.png
index 6e5e42f..1e06e05 100644
--- a/res/drawable-hdpi/progressbar_indeterminate_holo4.png
+++ b/res/drawable-hdpi/progressbar_indeterminate_holo4.png
Binary files differ
diff --git a/res/drawable-hdpi/progressbar_indeterminate_holo5.png b/res/drawable-hdpi/progressbar_indeterminate_holo5.png
index fe41b55..306d400 100644
--- a/res/drawable-hdpi/progressbar_indeterminate_holo5.png
+++ b/res/drawable-hdpi/progressbar_indeterminate_holo5.png
Binary files differ
diff --git a/res/drawable-hdpi/progressbar_indeterminate_holo6.png b/res/drawable-hdpi/progressbar_indeterminate_holo6.png
index 2ec95b8..f7d0cc3 100644
--- a/res/drawable-hdpi/progressbar_indeterminate_holo6.png
+++ b/res/drawable-hdpi/progressbar_indeterminate_holo6.png
Binary files differ
diff --git a/res/drawable-hdpi/progressbar_indeterminate_holo7.png b/res/drawable-hdpi/progressbar_indeterminate_holo7.png
index 2ea5e97..d30a676 100644
--- a/res/drawable-hdpi/progressbar_indeterminate_holo7.png
+++ b/res/drawable-hdpi/progressbar_indeterminate_holo7.png
Binary files differ
diff --git a/res/drawable-hdpi/progressbar_indeterminate_holo8.png b/res/drawable-hdpi/progressbar_indeterminate_holo8.png
index f6b764b..8fe443c 100644
--- a/res/drawable-hdpi/progressbar_indeterminate_holo8.png
+++ b/res/drawable-hdpi/progressbar_indeterminate_holo8.png
Binary files differ
diff --git a/res/drawable-hdpi/progressbar_solid_holo.png b/res/drawable-hdpi/progressbar_solid_holo.png
index a285bbc..0b9e2ff 100644
--- a/res/drawable-hdpi/progressbar_solid_holo.png
+++ b/res/drawable-hdpi/progressbar_solid_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_indeterminate_holo1.png b/res/drawable-mdpi/progressbar_indeterminate_holo1.png
index bc13597..460ecd1 100644
--- a/res/drawable-mdpi/progressbar_indeterminate_holo1.png
+++ b/res/drawable-mdpi/progressbar_indeterminate_holo1.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_indeterminate_holo2.png b/res/drawable-mdpi/progressbar_indeterminate_holo2.png
index f7ba10c..05d19a7 100644
--- a/res/drawable-mdpi/progressbar_indeterminate_holo2.png
+++ b/res/drawable-mdpi/progressbar_indeterminate_holo2.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_indeterminate_holo3.png b/res/drawable-mdpi/progressbar_indeterminate_holo3.png
index c5ce419..5a0bb00 100644
--- a/res/drawable-mdpi/progressbar_indeterminate_holo3.png
+++ b/res/drawable-mdpi/progressbar_indeterminate_holo3.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_indeterminate_holo4.png b/res/drawable-mdpi/progressbar_indeterminate_holo4.png
index 46f01d2..3f99453 100644
--- a/res/drawable-mdpi/progressbar_indeterminate_holo4.png
+++ b/res/drawable-mdpi/progressbar_indeterminate_holo4.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_indeterminate_holo5.png b/res/drawable-mdpi/progressbar_indeterminate_holo5.png
index 19a4d65..4a72b49 100644
--- a/res/drawable-mdpi/progressbar_indeterminate_holo5.png
+++ b/res/drawable-mdpi/progressbar_indeterminate_holo5.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_indeterminate_holo6.png b/res/drawable-mdpi/progressbar_indeterminate_holo6.png
index baf6b4a..aa54f41 100644
--- a/res/drawable-mdpi/progressbar_indeterminate_holo6.png
+++ b/res/drawable-mdpi/progressbar_indeterminate_holo6.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_indeterminate_holo7.png b/res/drawable-mdpi/progressbar_indeterminate_holo7.png
index 844968b..5a39510 100644
--- a/res/drawable-mdpi/progressbar_indeterminate_holo7.png
+++ b/res/drawable-mdpi/progressbar_indeterminate_holo7.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_indeterminate_holo8.png b/res/drawable-mdpi/progressbar_indeterminate_holo8.png
index 2045f5c..ac0a8e2 100644
--- a/res/drawable-mdpi/progressbar_indeterminate_holo8.png
+++ b/res/drawable-mdpi/progressbar_indeterminate_holo8.png
Binary files differ
diff --git a/res/drawable-mdpi/progressbar_solid_holo.png b/res/drawable-mdpi/progressbar_solid_holo.png
index e27c12a..c256c6d 100644
--- a/res/drawable-mdpi/progressbar_solid_holo.png
+++ b/res/drawable-mdpi/progressbar_solid_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_indeterminate_holo1.png b/res/drawable-xhdpi/progressbar_indeterminate_holo1.png
index 5ad2938..a28ee79 100644
--- a/res/drawable-xhdpi/progressbar_indeterminate_holo1.png
+++ b/res/drawable-xhdpi/progressbar_indeterminate_holo1.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_indeterminate_holo2.png b/res/drawable-xhdpi/progressbar_indeterminate_holo2.png
index 7cf2952..887ffff 100644
--- a/res/drawable-xhdpi/progressbar_indeterminate_holo2.png
+++ b/res/drawable-xhdpi/progressbar_indeterminate_holo2.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_indeterminate_holo3.png b/res/drawable-xhdpi/progressbar_indeterminate_holo3.png
index 1817344..1666d8e 100644
--- a/res/drawable-xhdpi/progressbar_indeterminate_holo3.png
+++ b/res/drawable-xhdpi/progressbar_indeterminate_holo3.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_indeterminate_holo4.png b/res/drawable-xhdpi/progressbar_indeterminate_holo4.png
index 29ab58e..26bb2d2 100644
--- a/res/drawable-xhdpi/progressbar_indeterminate_holo4.png
+++ b/res/drawable-xhdpi/progressbar_indeterminate_holo4.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_indeterminate_holo5.png b/res/drawable-xhdpi/progressbar_indeterminate_holo5.png
index 5a7f94f..6966e00 100644
--- a/res/drawable-xhdpi/progressbar_indeterminate_holo5.png
+++ b/res/drawable-xhdpi/progressbar_indeterminate_holo5.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_indeterminate_holo6.png b/res/drawable-xhdpi/progressbar_indeterminate_holo6.png
index 67b9554..c4f6b3d 100644
--- a/res/drawable-xhdpi/progressbar_indeterminate_holo6.png
+++ b/res/drawable-xhdpi/progressbar_indeterminate_holo6.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_indeterminate_holo7.png b/res/drawable-xhdpi/progressbar_indeterminate_holo7.png
index 0651224..a57c701 100644
--- a/res/drawable-xhdpi/progressbar_indeterminate_holo7.png
+++ b/res/drawable-xhdpi/progressbar_indeterminate_holo7.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_indeterminate_holo8.png b/res/drawable-xhdpi/progressbar_indeterminate_holo8.png
index a3de9f8..1bcae42 100644
--- a/res/drawable-xhdpi/progressbar_indeterminate_holo8.png
+++ b/res/drawable-xhdpi/progressbar_indeterminate_holo8.png
Binary files differ
diff --git a/res/drawable-xhdpi/progressbar_solid_holo.png b/res/drawable-xhdpi/progressbar_solid_holo.png
index b6f1779..1f7ff83 100644
--- a/res/drawable-xhdpi/progressbar_solid_holo.png
+++ b/res/drawable-xhdpi/progressbar_solid_holo.png
Binary files differ
diff --git a/res/layout/conversation_list.xml b/res/layout/conversation_list.xml
index f3ce26a..a882444 100644
--- a/res/layout/conversation_list.xml
+++ b/res/layout/conversation_list.xml
@@ -49,26 +49,6 @@
             android:fadingEdge="none"
             android:layout_alignParentTop="true"/>
 
-        <ProgressBar
-            android:id="@+id/sync_trigger"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="top|center"
-            android:visibility="gone"
-            style="?android:attr/progressBarStyleHorizontal"
-            android:max="100"
-            android:progress="100"
-            android:progressDrawable="@drawable/progressbar_solid_holo" />
-
-        <ProgressBar
-            android:id="@+id/progress"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="top"
-            android:visibility="gone"
-            android:indeterminateDrawable="@drawable/progress_indeterminate_horizontal_holo"
-            android:indeterminate="true" />
-
     </com.android.mail.ui.ConversationListView>
 
 </RelativeLayout>
diff --git a/res/layout/conversation_list_progress.xml b/res/layout/conversation_list_progress.xml
new file mode 100644
index 0000000..4a44c05
--- /dev/null
+++ b/res/layout/conversation_list_progress.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 Google Inc.
+     Licensed to 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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <ProgressBar
+        android:id="@+id/sync_trigger"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center"
+        android:visibility="gone"
+        style="?android:attr/progressBarStyleHorizontal"
+        android:max="100"
+        android:progress="100"
+        android:progressDrawable="@drawable/progressbar_solid_holo" />
+
+    <ProgressBar
+        android:id="@+id/progress"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top"
+        android:visibility="gone"
+        android:indeterminateDrawable="@drawable/progress_indeterminate_horizontal_holo"
+        android:indeterminate="true" />
+
+</merge>
diff --git a/src/com/android/mail/ui/ConversationListView.java b/src/com/android/mail/ui/ConversationListView.java
index 889596c..16bc17e 100644
--- a/src/com/android/mail/ui/ConversationListView.java
+++ b/src/com/android/mail/ui/ConversationListView.java
@@ -1,7 +1,6 @@
 package com.android.mail.ui;
 
 import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
 import android.app.Activity;
 import android.content.Context;
@@ -10,9 +9,7 @@
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.TypedValue;
-
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -50,7 +47,7 @@
 
     private View mSyncTriggerBar;
     private View mSyncProgressBar;
-    private AnimatorListenerAdapter mSyncProgressBarFadeListener;
+    private final AnimatorListenerAdapter mSyncDismissListener;
     private SwipeableListView mListView;
 
     // Whether to ignore events in {#dispatchTouchEvent}.
@@ -81,6 +78,14 @@
 
     private ConversationListContext mConvListContext;
 
+    private final Runnable mOnSyncDismiss = new Runnable() {
+        @Override
+        public void run() {
+            mSyncProgressBar.setVisibility(GONE);
+            mSyncTriggerBar.setVisibility(GONE);
+        }
+    };
+
     // Instantiated through view inflation
     @SuppressWarnings("unused")
     public ConversationListView(Context context) {
@@ -96,13 +101,25 @@
 
         mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
         mHintText = new ConversationListView.HintText(context);
+
+        mSyncDismissListener = new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator arg0) {
+                // Even though alpha is set to 0, still need to set visiblity to
+                // GONE, otherwise the progressbar animation continues to get drawn
+                // even though it's not visible.
+                //
+                // For some reason, setting this visibility to GONE immediately upon animation end
+                // occasionally does not terminate the periodic drawing of the progress bar.
+                // Posting it seems to alleviate this...
+                post(mOnSyncDismiss);
+            }
+        };
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mSyncTriggerBar = findViewById(R.id.sync_trigger);
-        mSyncProgressBar = findViewById(R.id.progress);
         mListView = (SwipeableListView) findViewById(android.R.id.list);
         mListView.setSwipeListener(this);
 
@@ -115,16 +132,6 @@
         mDistanceToTriggerSyncDp = Math.max(
                 Math.min(threshold, MAX_DISTANCE_TO_TRIGGER_SYNC),
                 MIN_DISTANCE_TO_TRIGGER_SYNC);
-
-        mSyncProgressBarFadeListener = new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator arg0) {
-                // Even though alpha is set to 0, still need to set visiblity to
-                // GONE, otherwise the progressbar animation continues to get drawn
-                // even though it's not visible.
-                mSyncProgressBar.setVisibility(GONE);
-            }
-        };
     }
 
     protected void setActivity(ControllableActivity activity) {
@@ -218,7 +225,7 @@
                     } else {
                         mHintText.displaySwipeToRefresh();
                     }
-                    mSyncTriggerBar.setScaleX(mAccelerateInterpolator.getInterpolation(
+                    setTriggerScale(mAccelerateInterpolator.getInterpolation(
                             verticalDistanceDp/mDistanceToTriggerSyncDp));
 
                     if (y > mTrackingScrollMaxY) {
@@ -242,23 +249,49 @@
         mTrackingScrollMovement = true;
         mTrackingScrollStartY = y;
         mTrackingScrollMaxY = mTrackingScrollStartY;
-
-        mSyncTriggerBar.setScaleX(0f);
-        mSyncTriggerBar.setAlpha(1f);
-        mSyncTriggerBar.setVisibility(VISIBLE);
     }
 
     private void cancelMovementTracking() {
         if (mTrackingScrollMovement) {
             // Shrink the status bar when user lifts finger and no sync has happened yet
-            mSyncTriggerBar.animate().scaleX(0f).setInterpolator(mDecelerateInterpolator)
-                    .setDuration(SYNC_TRIGGER_SHRINK_DURATION_IN_MILLIS).start();
+            if (mSyncTriggerBar != null) {
+                mSyncTriggerBar.animate()
+                        .scaleX(0f)
+                        .setInterpolator(mDecelerateInterpolator)
+                        .setDuration(SYNC_TRIGGER_SHRINK_DURATION_IN_MILLIS)
+                        .setListener(mSyncDismissListener)
+                        .start();
+            }
+            mTrackingScrollMovement = false;
         }
-        mTrackingScrollMovement = false;
         mHintText.hide();
     }
 
+    private void setTriggerScale(float scale) {
+        if (scale == 0f && mSyncTriggerBar == null) {
+            // No-op. A null trigger means it's uninitialized, and setting it to zero-scale
+            // means we're trying to reset state, so there's nothing to reset in this case.
+            return;
+        } else if (mSyncTriggerBar != null) {
+            // reset any leftover trigger visual state
+            mSyncTriggerBar.animate().cancel();
+            mSyncTriggerBar.setVisibility(VISIBLE);
+        }
+        ensureProgressBars();
+        mSyncTriggerBar.setScaleX(scale);
+    }
+
+    private void ensureProgressBars() {
+        if (mSyncTriggerBar == null || mSyncProgressBar == null) {
+            final LayoutInflater inflater = LayoutInflater.from(getContext());
+            inflater.inflate(R.layout.conversation_list_progress, this, true /* attachToRoot */);
+            mSyncTriggerBar = findViewById(R.id.sync_trigger);
+            mSyncProgressBar = findViewById(R.id.progress);
+        }
+    }
+
     private void triggerSync() {
+        ensureProgressBars();
         mSyncTriggerBar.setVisibility(View.GONE);
 
         // This will call back to showSyncStatusBar():
@@ -275,6 +308,7 @@
             mIsSyncing = true;
 
             LogUtils.i(LOG_TAG, "ConversationListView show sync status bar");
+            ensureProgressBars();
             mSyncTriggerBar.setVisibility(GONE);
             mSyncProgressBar.setVisibility(VISIBLE);
             mSyncProgressBar.setAlpha(1f);
@@ -289,7 +323,7 @@
             // Hide both the sync progress bar and sync trigger bar
             mSyncProgressBar.animate().alpha(0f)
                     .setDuration(SYNC_STATUS_BAR_FADE_DURATION_IN_MILLIS)
-                    .setListener(mSyncProgressBarFadeListener);
+                    .setListener(mSyncDismissListener);
             mSyncTriggerBar.setVisibility(GONE);
             // Hide the "Checking for mail" text in action bar if it isn't hidden already:
             mHintText.hide();