Adjustments for sample config watch face activity.

bug: 18321895
Change-Id: I576d415ad8c26ebc9496f233af6fd766618ed1f8
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceWearableConfigActivity.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceWearableConfigActivity.java
index a2e5251..4b309e6 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceWearableConfigActivity.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceWearableConfigActivity.java
@@ -16,16 +16,23 @@
 
 package com.example.android.wearable.watchface;
 
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.app.Activity;
+import android.content.Context;
 import android.graphics.Color;
 import android.os.Bundle;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
+import android.support.wearable.view.BoxInsetLayout;
+import android.support.wearable.view.CircledImageView;
 import android.support.wearable.view.WearableListView;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowInsets;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.google.android.gms.common.ConnectionResult;
@@ -37,25 +44,39 @@
  * The watch-side config activity for {@link DigitalWatchFaceService}, which allows for setting the
  * background color.
  */
-public class DigitalWatchFaceWearableConfigActivity extends Activity
-        implements WearableListView.ClickListener {
+public class DigitalWatchFaceWearableConfigActivity extends Activity implements
+        WearableListView.ClickListener, WearableListView.OnScrollListener {
     private static final String TAG = "DigitalWatchFaceConfig";
 
     private GoogleApiClient mGoogleApiClient;
+    private TextView mHeader;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_digital_config);
 
+        mHeader = (TextView) findViewById(R.id.header);
         WearableListView listView = (WearableListView) findViewById(R.id.color_picker);
+        BoxInsetLayout content = (BoxInsetLayout) findViewById(R.id.content);
+        // BoxInsetLayout adds padding by default on round devices. Add some on square devices.
+        content.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
+            @Override
+            public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
+                if (!insets.isRound()) {
+                    v.setPaddingRelative(
+                            (int) getResources().getDimensionPixelSize(R.dimen.content_padding_start),
+                            v.getPaddingTop(),
+                            v.getPaddingEnd(),
+                            v.getPaddingBottom());
+                }
+                return v.onApplyWindowInsets(insets);
+            }
+        });
 
         listView.setHasFixedSize(true);
         listView.setClickListener(this);
-
-        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
-        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
-        listView.setLayoutManager(layoutManager);
+        listView.addOnScrollListener(this);
 
         String[] colors = getResources().getStringArray(R.array.color_array);
         listView.setAdapter(new ColorListAdapter(colors));
@@ -105,11 +126,28 @@
     @Override // WearableListView.ClickListener
     public void onClick(WearableListView.ViewHolder viewHolder) {
         ColorItemViewHolder colorItemViewHolder = (ColorItemViewHolder) viewHolder;
-        String colorName = colorItemViewHolder.mLabel.getText().toString();
-        updateConfigDataItem(Color.parseColor(colorName));
+        updateConfigDataItem(colorItemViewHolder.mColorItem.getColor());
         finish();
     }
 
+    @Override // WearableListView.ClickListener
+    public void onTopEmptyRegionClick() {}
+
+    @Override // WearableListView.OnScrollListener
+    public void onScroll(int scroll) {}
+
+    @Override // WearableListView.OnScrollListener
+    public void onAbsoluteScrollChange(int scroll) {
+        float newTranslation = Math.min(-scroll, 0);
+        mHeader.setTranslationY(newTranslation);
+    }
+
+    @Override // WearableListView.OnScrollListener
+    public void onScrollStateChanged(int scrollState) {}
+
+    @Override // WearableListView.OnScrollListener
+    public void onCentralPositionChanged(int centralPosition) {}
+
     private void updateConfigDataItem(final int backgroundColor) {
         DataMap configKeysToOverwrite = new DataMap();
         configKeysToOverwrite.putInt(DigitalWatchFaceUtil.KEY_BACKGROUND_COLOR,
@@ -117,11 +155,7 @@
         DigitalWatchFaceUtil.overwriteKeysInConfigDataMap(mGoogleApiClient, configKeysToOverwrite);
     }
 
-    @Override // WearableListView.ClickListener
-    public void onTopEmptyRegionClick() { }
-
-    private class ColorListAdapter extends RecyclerView.Adapter<ColorItemViewHolder> {
-
+    private class ColorListAdapter extends WearableListView.Adapter {
         private final String[] mColors;
 
         public ColorListAdapter(String[] colors) {
@@ -130,16 +164,14 @@
 
         @Override
         public ColorItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-            View root = LayoutInflater.from(parent.getContext())
-                    .inflate(R.layout.color_picker_item, parent, false /* attachToRoot */);
-            TextView label = (TextView) root.findViewById(R.id.label);
-            return new ColorItemViewHolder(root, label);
+            return new ColorItemViewHolder(new ColorItem(parent.getContext()));
         }
 
         @Override
-        public void onBindViewHolder(ColorItemViewHolder holder, int position) {
+        public void onBindViewHolder(WearableListView.ViewHolder holder, int position) {
+            ColorItemViewHolder colorItemViewHolder = (ColorItemViewHolder) holder;
             String colorName = mColors[position];
-            holder.mLabel.setText(colorName);
+            colorItemViewHolder.mColorItem.setColor(colorName);
 
             RecyclerView.LayoutParams layoutParams =
                     new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
@@ -154,7 +186,7 @@
             } else {
                 layoutParams.setMargins(0, 0, 0, 0);
             }
-            holder.itemView.setLayoutParams(layoutParams);
+            colorItemViewHolder.itemView.setLayoutParams(layoutParams);
         }
 
         @Override
@@ -163,12 +195,104 @@
         }
     }
 
-    private static class ColorItemViewHolder extends WearableListView.ViewHolder {
-        private final TextView mLabel;
+    /** The layout of a color item including image and label. */
+    private static class ColorItem extends LinearLayout implements
+            WearableListView.OnCenterProximityListener {
+        /** The duration of the expand/shrink animation. */
+        private static final int ANIMATION_DURATION_MS = 150;
+        /** The ratio for the size of a circle in shrink state. */
+        private static final float SHRINK_CIRCLE_RATIO = .75f;
 
-        public ColorItemViewHolder(View root, TextView label) {
-            super(root);
-            this.mLabel = label;
+        private static final float SHRINK_LABEL_ALPHA = .5f;
+        private static final float EXPAND_LABEL_ALPHA = 1f;
+
+        private final TextView mLabel;
+        private final CircledImageView mColor;
+
+        private final float mExpandCircleRadius;
+        private final float mShrinkCircleRadius;
+
+        private final ObjectAnimator mExpandCircleAnimator;
+        private final ObjectAnimator mExpandLabelAnimator;
+        private final AnimatorSet mExpandAnimator;
+
+        private final ObjectAnimator mShrinkCircleAnimator;
+        private final ObjectAnimator mShrinkLabelAnimator;
+        private final AnimatorSet mShrinkAnimator;
+
+        public ColorItem(Context context) {
+            super(context);
+            View.inflate(context, R.layout.color_picker_item, this);
+
+            mLabel = (TextView) findViewById(R.id.label);
+            mColor = (CircledImageView) findViewById(R.id.color);
+
+            mExpandCircleRadius = mColor.getCircleRadius();
+            mShrinkCircleRadius = mExpandCircleRadius * SHRINK_CIRCLE_RATIO;
+
+            mShrinkCircleAnimator = ObjectAnimator.ofFloat(mColor, "circleRadius",
+                    mExpandCircleRadius, mShrinkCircleRadius);
+            mShrinkLabelAnimator = ObjectAnimator.ofFloat(mLabel, "alpha",
+                    EXPAND_LABEL_ALPHA, SHRINK_LABEL_ALPHA);
+            mShrinkAnimator = new AnimatorSet().setDuration(ANIMATION_DURATION_MS);
+            mShrinkAnimator.playTogether(mShrinkCircleAnimator, mShrinkLabelAnimator);
+
+            mExpandCircleAnimator = ObjectAnimator.ofFloat(mColor, "circleRadius",
+                    mShrinkCircleRadius, mExpandCircleRadius);
+            mExpandLabelAnimator = ObjectAnimator.ofFloat(mLabel, "alpha",
+                    SHRINK_LABEL_ALPHA, EXPAND_LABEL_ALPHA);
+            mExpandAnimator = new AnimatorSet().setDuration(ANIMATION_DURATION_MS);
+            mExpandAnimator.playTogether(mExpandCircleAnimator, mExpandLabelAnimator);
+        }
+
+        @Override
+        public void onCenterPosition(boolean animate) {
+            if (animate) {
+                mShrinkAnimator.cancel();
+                if (!mExpandAnimator.isRunning()) {
+                    mExpandCircleAnimator.setFloatValues(mColor.getCircleRadius(), mExpandCircleRadius);
+                    mExpandLabelAnimator.setFloatValues(mLabel.getAlpha(), EXPAND_LABEL_ALPHA);
+                    mExpandAnimator.start();
+                }
+            } else {
+                mExpandAnimator.cancel();
+                mColor.setCircleRadius(mExpandCircleRadius);
+                mLabel.setAlpha(EXPAND_LABEL_ALPHA);
+            }
+        }
+
+        @Override
+        public void onNonCenterPosition(boolean animate) {
+            if (animate) {
+                mExpandAnimator.cancel();
+                if (!mShrinkAnimator.isRunning()) {
+                    mShrinkCircleAnimator.setFloatValues(mColor.getCircleRadius(), mShrinkCircleRadius);
+                    mShrinkLabelAnimator.setFloatValues(mLabel.getAlpha(), SHRINK_LABEL_ALPHA);
+                    mShrinkAnimator.start();
+                }
+            } else {
+                mShrinkAnimator.cancel();
+                mColor.setCircleRadius(mShrinkCircleRadius);
+                mLabel.setAlpha(SHRINK_LABEL_ALPHA);
+            }
+        }
+
+        private void setColor(String colorName) {
+            mLabel.setText(colorName);
+            mColor.setCircleColor(Color.parseColor(colorName));
+        }
+
+        private int getColor() {
+            return mColor.getDefaultCircleColor();
+        }
+    }
+
+    private static class ColorItemViewHolder extends WearableListView.ViewHolder {
+        private final ColorItem mColorItem;
+
+        public ColorItemViewHolder(ColorItem colorItem) {
+            super(colorItem);
+            mColorItem = colorItem;
         }
     }
 }
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_digital_config.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_digital_config.xml
index eef7aae..a368390 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_digital_config.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_digital_config.xml
@@ -13,25 +13,27 @@
  See the License for the specific language governing permissions and
  limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/content"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:background="#ffffff">
+    android:background="@color/config_activity_background">
     <TextView
         android:id="@+id/header"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginLeft="16dp"
         android:layout_marginTop="14dp"
-        android:layout_gravity="center_horizontal"
-        android:textSize="22sp"
-        android:textColor="#a2a2a2"
+        android:textSize="24sp"
+        android:textColor="@color/config_activity_header_text_color"
         android:text="@string/digital_background_color"
-        android:fontFamily="sans-serif-condensed-light"/>
+        android:fontFamily="sans-serif-condensed-light"
+        app:layout_box="left|top"/>
     <android.support.wearable.view.WearableListView
         android:id="@+id/color_picker"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="@android:color/transparent"/>
-</LinearLayout>
+        android:background="@android:color/transparent"
+        app:layout_box="left|right"/>
+</android.support.wearable.view.BoxInsetLayout>
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/color_picker_item.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/color_picker_item.xml
index e7edb39..9b07e2a 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/layout/color_picker_item.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/color_picker_item.xml
@@ -13,14 +13,26 @@
  See the License for the specific language governing permissions and
  limitations under the License.
 -->
-<TextView
+<merge
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/label"
-    android:fontFamily="sans-serif-condensed-light"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:gravity="center_horizontal"
-    android:paddingTop="20dp"
-    android:paddingBottom="20dp"
-    android:textColor="#000000"
-    android:textSize="18sp"/>
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <android.support.wearable.view.CircledImageView
+        android:id="@+id/color"
+        android:layout_width="52dp"
+        android:layout_height="52dp"
+        android:layout_gravity="center_vertical"
+        app:circle_border_color="@color/color_item_circle_border_color"
+        app:circle_radius="26dp"
+        app:circle_border_width="1dp"/>
+
+    <TextView
+        android:id="@+id/label"
+        android:fontFamily="sans-serif-condensed-light"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:layout_marginLeft="10dp"
+        android:textColor="@color/color_item_label_color"
+        android:textSize="18sp"/>
+</merge>
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/values/color.xml b/wearable/wear/WatchFace/Wearable/src/main/res/values/color.xml
index 2ba1355..0da08ed 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/values/color.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/color.xml
@@ -16,4 +16,8 @@
 <resources>
     <color name="digital_am_pm">#aaaaa0</color>
     <color name="digital_colons">#aaaaa0</color>
+    <color name="config_activity_background">#ffffff</color>
+    <color name="config_activity_header_text_color">#959595</color>
+    <color name="color_item_label_color">#000000</color>
+    <color name="color_item_circle_border_color">#424242</color>
 </resources>
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/values/dimens.xml b/wearable/wear/WatchFace/Wearable/src/main/res/values/dimens.xml
index b9c4c86..8f04e56 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/values/dimens.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/dimens.xml
@@ -22,4 +22,5 @@
     <dimen name="digital_x_offset_round">25dp</dimen>
     <dimen name="digital_y_offset">90dp</dimen>
     <dimen name="digital_config_color_picker_item_margin">32dp</dimen>
+    <dimen name="content_padding_start">12dp</dimen>
 </resources>