Extract SwipeableShortcutCard into its own class

Intial work to separate shortcut card view logic and the actual adapter
to prepare for removal of the shortcut cards list view.

Change-Id: Ie102fcd1d0d7be13c326cdf4c47502194a2f5ad6
diff --git a/src/com/android/dialer/list/ListsFragment.java b/src/com/android/dialer/list/ListsFragment.java
index 7a5376c..e9ce57b 100644
--- a/src/com/android/dialer/list/ListsFragment.java
+++ b/src/com/android/dialer/list/ListsFragment.java
@@ -29,7 +29,6 @@
 import com.android.dialer.calllog.CallLogQuery;
 import com.android.dialer.calllog.CallLogQueryHandler;
 import com.android.dialer.calllog.ContactInfoHelper;
-import com.android.dialer.list.ShortcutCardsAdapter.SwipeableShortcutCard;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.widget.ActionBarController;
 import com.android.dialer.widget.OverlappingPaneLayout;
diff --git a/src/com/android/dialer/list/ShortcutCardsAdapter.java b/src/com/android/dialer/list/ShortcutCardsAdapter.java
index 6410eab..ad6a61c 100644
--- a/src/com/android/dialer/list/ShortcutCardsAdapter.java
+++ b/src/com/android/dialer/list/ShortcutCardsAdapter.java
@@ -20,23 +20,14 @@
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.DataSetObserver;
-import android.graphics.Rect;
-import android.text.TextUtils;
-import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.TextView;
 
-import com.android.dialer.R;
 import com.android.dialer.calllog.CallLogAdapter;
 import com.android.dialer.calllog.CallLogNotificationsHelper;
 import com.android.dialer.calllog.CallLogQueryHandler;
 import com.android.dialer.list.SwipeHelper.OnItemGestureListener;
-import com.android.dialer.list.SwipeHelper.SwipeHelperCallback;
 
 /**
  * An adapter that displays call shortcuts from {@link com.android.dialer.calllog.CallLogAdapter}
@@ -52,24 +43,11 @@
     }
 
     private static final String TAG = ShortcutCardsAdapter.class.getSimpleName();
-    private static final float CLIP_CARD_BARELY_HIDDEN_RATIO = 0.001f;
-    private static final float CLIP_CARD_MOSTLY_HIDDEN_RATIO = 0.9f;
-    // Fade out 5x faster than the hidden ratio.
-    private static final float CLIP_CARD_OPACITY_RATIO = 5f;
 
     private final CallLogAdapter mCallLogAdapter;
 
     private final ListsFragment mFragment;
 
-    private final int mCallLogMarginHorizontal;
-    private final int mCallLogMarginTop;
-    private final int mCallLogMarginBottom;
-    private final int mCallLogPaddingStart;
-    private final int mCallLogPaddingTop;
-    private final int mCallLogPaddingBottom;
-    private final int mCardMaxHorizontalClip;
-    private final int mShortCardBackgroundColor;
-
     private final Context mContext;
 
     private final DataSetObserver mObserver;
@@ -117,22 +95,6 @@
         final Resources resources = context.getResources();
         mContext = context;
         mFragment = fragment;
-        mCardMaxHorizontalClip =
-                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_horizontal_clip_limit);
-        mCallLogMarginHorizontal =
-                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_margin_horizontal);
-        mCallLogMarginTop =
-                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_margin_top);
-        mCallLogMarginBottom =
-                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_margin_bottom);
-        mCallLogPaddingStart =
-                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_padding_start);
-        mCallLogPaddingTop =
-                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_padding_top);
-        mCallLogPaddingBottom =
-                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_padding_bottom);
-        mShortCardBackgroundColor = resources.getColor(R.color.call_log_expanded_background_color);
-
 
         mCallLogAdapter = callLogAdapter;
         mObserver = new CustomDataSetObserver();
@@ -215,179 +177,4 @@
     public boolean isEnabled(int position) {
         return mCallLogAdapter.isEnabled(position);
     }
-
-    /**
-     * The swipeable call log row.
-     */
-    class SwipeableShortcutCard extends FrameLayout implements SwipeHelperCallback {
-        private SwipeHelper mSwipeHelper;
-        private OnItemGestureListener mOnItemSwipeListener;
-
-        private float mPreviousTranslationZ = 0;
-        private Rect mClipRect = new Rect();
-
-        public SwipeableShortcutCard(Context context) {
-            super(context);
-            final float densityScale = getResources().getDisplayMetrics().density;
-            final float pagingTouchSlop = ViewConfiguration.get(context)
-                    .getScaledPagingTouchSlop();
-            mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this,
-                    densityScale, pagingTouchSlop);
-        }
-
-        private void prepareChildView(View view) {
-            // Override CallLogAdapter's accessibility behavior; don't expand the shortcut card.
-            view.setAccessibilityDelegate(null);
-            view.setBackgroundResource(R.drawable.rounded_corner_bg);
-
-            final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
-                    FrameLayout.LayoutParams.MATCH_PARENT,
-                    FrameLayout.LayoutParams.WRAP_CONTENT);
-            params.setMargins(
-                    mCallLogMarginHorizontal,
-                    mCallLogMarginTop,
-                    mCallLogMarginHorizontal,
-                    mCallLogMarginBottom);
-            view.setLayoutParams(params);
-
-            LinearLayout actionView =
-                    (LinearLayout) view.findViewById(R.id.primary_action_view);
-            actionView.setPaddingRelative(
-                    mCallLogPaddingStart,
-                    mCallLogPaddingTop,
-                    actionView.getPaddingEnd(),
-                    mCallLogPaddingBottom);
-
-            // TODO: Set content description including type/location and time information.
-            TextView nameView = (TextView) actionView.findViewById(R.id.name);
-
-            actionView.setContentDescription(
-                    TextUtils.expandTemplate(
-                            getResources().getString(R.string.description_call_back_action),
-                            nameView.getText()));
-
-            mPreviousTranslationZ = getResources().getDimensionPixelSize(
-                    R.dimen.recent_call_log_item_translation_z);
-            view.setTranslationZ(mPreviousTranslationZ);
-
-            final ViewGroup callLogItem = (ViewGroup) view.findViewById(R.id.call_log_list_item);
-            // Reset the internal call log item view if it is being recycled
-            callLogItem.setTranslationX(0);
-            callLogItem.setTranslationY(0);
-            callLogItem.setAlpha(1);
-            callLogItem.setClipBounds(null);
-            setChildrenOpacity(callLogItem, 1.0f);
-
-            callLogItem.findViewById(R.id.call_log_row)
-                    .setBackgroundColor(mShortCardBackgroundColor);
-
-            callLogItem.findViewById(R.id.call_indicator_icon).setVisibility(View.VISIBLE);
-        }
-
-        @Override
-        public View getChildAtPosition(MotionEvent ev) {
-            return getChildCount() > 0 ? getChildAt(0) : null;
-        }
-
-        @Override
-        public View getChildContentView(View v) {
-            return v.findViewById(R.id.call_log_list_item);
-        }
-
-        @Override
-        public void onScroll() {}
-
-        @Override
-        public boolean canChildBeDismissed(View v) {
-            return true;
-        }
-
-        @Override
-        public void onBeginDrag(View v) {
-            // We do this so the underlying ScrollView knows that it won't get
-            // the chance to intercept events anymore
-            requestDisallowInterceptTouchEvent(true);
-        }
-
-        @Override
-        public void onChildDismissed(View v) {
-            if (v != null && mOnItemSwipeListener != null) {
-                mOnItemSwipeListener.onSwipe(v);
-            }
-        }
-
-        @Override
-        public void onDragCancelled(View v) {}
-
-        @Override
-        public boolean onInterceptTouchEvent(MotionEvent ev) {
-            if (mSwipeHelper != null) {
-                return mSwipeHelper.onInterceptTouchEvent(ev) || super.onInterceptTouchEvent(ev);
-            } else {
-                return super.onInterceptTouchEvent(ev);
-            }
-        }
-
-        @Override
-        public boolean onTouchEvent(MotionEvent ev) {
-            if (mSwipeHelper != null) {
-                return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
-            } else {
-                return super.onTouchEvent(ev);
-            }
-        }
-
-        public void setOnItemSwipeListener(OnItemGestureListener listener) {
-            mOnItemSwipeListener = listener;
-        }
-
-        /**
-         * Clips the card by a specified amount.
-         *
-         * @param ratioHidden A float indicating how much of each edge of the card should be
-         *         clipped. If 0, the entire card is displayed. If 0.5f, each edge is hidden
-         *         entirely, thus obscuring the entire card.
-         */
-        public void clipCard(float ratioHidden) {
-            final View viewToClip = getChildAt(0);
-            if (viewToClip == null) {
-                return;
-            }
-            int width = viewToClip.getWidth();
-            int height = viewToClip.getHeight();
-
-            if (ratioHidden <= CLIP_CARD_BARELY_HIDDEN_RATIO) {
-                viewToClip.setTranslationZ(mPreviousTranslationZ);
-            } else if (viewToClip.getTranslationZ() != 0){
-                mPreviousTranslationZ = viewToClip.getTranslationZ();
-                viewToClip.setTranslationZ(0);
-            }
-
-            if (ratioHidden > CLIP_CARD_MOSTLY_HIDDEN_RATIO) {
-                mClipRect.set(0, 0 , 0, 0);
-                setVisibility(View.INVISIBLE);
-            } else {
-                setVisibility(View.VISIBLE);
-                int newTop = (int) (ratioHidden * height);
-                mClipRect.set(0, newTop, width, height);
-
-                // Since the pane will be overlapping with the action bar, apply a vertical offset
-                // to top align the clipped card in the viewable area;
-                viewToClip.setTranslationY(-newTop);
-            }
-            viewToClip.setClipBounds(mClipRect);
-
-            // If the view has any children, fade them out of view.
-            final ViewGroup viewGroup = (ViewGroup) viewToClip;
-            setChildrenOpacity(
-                    viewGroup, Math.max(0, 1 - (CLIP_CARD_OPACITY_RATIO  * ratioHidden)));
-        }
-
-        private void setChildrenOpacity(ViewGroup viewGroup, float alpha) {
-            final int count = viewGroup.getChildCount();
-            for (int i = 0; i < count; i++) {
-                viewGroup.getChildAt(i).setAlpha(alpha);
-            }
-        }
-    }
 }
diff --git a/src/com/android/dialer/list/SwipeableShortcutCard.java b/src/com/android/dialer/list/SwipeableShortcutCard.java
new file mode 100644
index 0000000..93e9fff
--- /dev/null
+++ b/src/com/android/dialer/list/SwipeableShortcutCard.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+package com.android.dialer.list;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.text.TextUtils;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.dialer.R;
+import com.android.dialer.list.SwipeHelper.OnItemGestureListener;
+import com.android.dialer.list.SwipeHelper.SwipeHelperCallback;
+
+/**
+ * The swipeable call log row.
+ */
+public class SwipeableShortcutCard extends FrameLayout implements SwipeHelperCallback {
+
+    private static final float CLIP_CARD_BARELY_HIDDEN_RATIO = 0.001f;
+    private static final float CLIP_CARD_MOSTLY_HIDDEN_RATIO = 0.9f;
+    // Fade out 5x faster than the hidden ratio.
+    private static final float CLIP_CARD_OPACITY_RATIO = 5f;
+
+    final int mCallLogMarginHorizontal;
+    final int mCallLogMarginTop;
+    final int mCallLogMarginBottom;
+    final int mCallLogPaddingStart;
+    final int mCallLogPaddingTop;
+    final int mCallLogPaddingBottom;
+    final int mShortCardBackgroundColor;
+
+    private SwipeHelper mSwipeHelper;
+    private OnItemGestureListener mOnItemSwipeListener;
+
+    private float mPreviousTranslationZ = 0;
+    private Rect mClipRect = new Rect();
+
+    public SwipeableShortcutCard(Context context) {
+        super(context);
+        final Resources resources = getResources();
+        final float densityScale =resources.getDisplayMetrics().density;
+        final float pagingTouchSlop = ViewConfiguration.get(context)
+                .getScaledPagingTouchSlop();
+        mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this,
+                densityScale, pagingTouchSlop);
+
+        mCallLogMarginHorizontal =
+                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_margin_horizontal);
+        mCallLogMarginTop =
+                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_margin_top);
+        mCallLogMarginBottom =
+                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_margin_bottom);
+        mCallLogPaddingStart =
+                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_padding_start);
+        mCallLogPaddingTop =
+                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_padding_top);
+        mCallLogPaddingBottom =
+                resources.getDimensionPixelSize(R.dimen.recent_call_log_item_padding_bottom);
+        mShortCardBackgroundColor =
+                resources.getColor(R.color.call_log_expanded_background_color, null);
+    }
+
+    void prepareChildView(View view) {
+        // Override CallLogAdapter's accessibility behavior; don't expand the shortcut card.
+        view.setAccessibilityDelegate(null);
+        view.setBackgroundResource(R.drawable.rounded_corner_bg);
+
+        final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.MATCH_PARENT,
+                FrameLayout.LayoutParams.WRAP_CONTENT);
+        params.setMargins(mCallLogMarginHorizontal, mCallLogMarginTop, mCallLogMarginHorizontal,
+                mCallLogMarginBottom);
+        view.setLayoutParams(params);
+
+        LinearLayout actionView =
+                (LinearLayout) view.findViewById(R.id.primary_action_view);
+        actionView.setPaddingRelative(mCallLogPaddingStart, mCallLogPaddingTop,
+                actionView.getPaddingEnd(), mCallLogPaddingBottom);
+
+        // TODO: Set content description including type/location and time information.
+        TextView nameView = (TextView) actionView.findViewById(R.id.name);
+
+        actionView.setContentDescription(
+                TextUtils.expandTemplate(
+                        getResources().getString(R.string.description_call_back_action),
+                        nameView.getText()));
+
+        mPreviousTranslationZ = getResources().getDimensionPixelSize(
+                R.dimen.recent_call_log_item_translation_z);
+        view.setTranslationZ(mPreviousTranslationZ);
+
+        final ViewGroup callLogItem = (ViewGroup) view.findViewById(R.id.call_log_list_item);
+        // Reset the internal call log item view if it is being recycled
+        callLogItem.setTranslationX(0);
+        callLogItem.setTranslationY(0);
+        callLogItem.setAlpha(1);
+        callLogItem.setClipBounds(null);
+        setChildrenOpacity(callLogItem, 1.0f);
+
+        callLogItem.findViewById(R.id.call_log_row)
+                .setBackgroundColor(mShortCardBackgroundColor);
+
+        callLogItem.findViewById(R.id.call_indicator_icon).setVisibility(View.VISIBLE);
+    }
+
+    @Override
+    public View getChildAtPosition(MotionEvent ev) {
+        return getChildCount() > 0 ? getChildAt(0) : null;
+    }
+
+    @Override
+    public View getChildContentView(View v) {
+        return v.findViewById(R.id.call_log_list_item);
+    }
+
+    @Override
+    public void onScroll() {}
+
+    @Override
+    public boolean canChildBeDismissed(View v) {
+        return true;
+    }
+
+    @Override
+    public void onBeginDrag(View v) {
+        // We do this so the underlying ScrollView knows that it won't get
+        // the chance to intercept events anymore
+        requestDisallowInterceptTouchEvent(true);
+    }
+
+    @Override
+    public void onChildDismissed(View v) {
+        if (v != null && mOnItemSwipeListener != null) {
+            mOnItemSwipeListener.onSwipe(v);
+        }
+    }
+
+    @Override
+    public void onDragCancelled(View v) {}
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mSwipeHelper != null) {
+            return mSwipeHelper.onInterceptTouchEvent(ev) || super.onInterceptTouchEvent(ev);
+        } else {
+            return super.onInterceptTouchEvent(ev);
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (mSwipeHelper != null) {
+            return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
+        } else {
+            return super.onTouchEvent(ev);
+        }
+    }
+
+    public void setOnItemSwipeListener(OnItemGestureListener listener) {
+        mOnItemSwipeListener = listener;
+    }
+
+    /**
+     * Clips the card by a specified amount.
+     *
+     * @param ratioHidden A float indicating how much of each edge of the card should be
+     *         clipped. If 0, the entire card is displayed. If 0.5f, each edge is hidden
+     *         entirely, thus obscuring the entire card.
+     */
+    public void clipCard(float ratioHidden) {
+        final View viewToClip = getChildAt(0);
+        if (viewToClip == null) {
+            return;
+        }
+        int width = viewToClip.getWidth();
+        int height = viewToClip.getHeight();
+
+        if (ratioHidden <= CLIP_CARD_BARELY_HIDDEN_RATIO) {
+            viewToClip.setTranslationZ(mPreviousTranslationZ);
+        } else if (viewToClip.getTranslationZ() != 0){
+            mPreviousTranslationZ = viewToClip.getTranslationZ();
+            viewToClip.setTranslationZ(0);
+        }
+
+        if (ratioHidden > CLIP_CARD_MOSTLY_HIDDEN_RATIO) {
+            mClipRect.set(0, 0 , 0, 0);
+            setVisibility(View.INVISIBLE);
+        } else {
+            setVisibility(View.VISIBLE);
+            int newTop = (int) (ratioHidden * height);
+            mClipRect.set(0, newTop, width, height);
+
+            // Since the pane will be overlapping with the action bar, apply a vertical offset
+            // to top align the clipped card in the viewable area;
+            viewToClip.setTranslationY(-newTop);
+        }
+        viewToClip.setClipBounds(mClipRect);
+
+        // If the view has any children, fade them out of view.
+        final ViewGroup viewGroup = (ViewGroup) viewToClip;
+        setChildrenOpacity(
+                viewGroup, Math.max(0, 1 - (CLIP_CARD_OPACITY_RATIO  * ratioHidden)));
+    }
+
+    private void setChildrenOpacity(ViewGroup viewGroup, float alpha) {
+        final int count = viewGroup.getChildCount();
+        for (int i = 0; i < count; i++) {
+            viewGroup.getChildAt(i).setAlpha(alpha);
+        }
+    }
+}
\ No newline at end of file