Show separate pressed effect for primary/secondary actions

Previously the whole content is highlightened by users'
item selection. Now we have two separate touch targets.

Affects Contact detail screen and quick contacts. In the
future we need to do similar thing to CallLog screen too.

- stop using onItemClick() but handle two separate onClick
  events
- modify layouts so that we can show correct "pressed"
  look-and-feel
- prepare two focusable Views for keyboard navigation

Bug: 5042772
Change-Id: I548f2e4ba11043081b3444f6eb341364bf71d917
diff --git a/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml b/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
index 22f0412..4cb4096 100644
--- a/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
+++ b/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
@@ -17,120 +17,115 @@
  */
 -->
 
+<!-- Note: padding might be controlled programatically -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="vertical">
+    android:orientation="horizontal"
+    android:gravity="center_vertical"
+    android:minHeight="@dimen/detail_min_line_item_height">
 
-    <LinearLayout
-        android:layout_width="match_parent"
+    <!-- Note: padding might be controlled programatically -->
+    <com.android.contacts.detail.PrimaryActionViewContainer
+        android:id="@+id/primary_action_view_container"
+        android:layout_width="0dip"
+        android:layout_weight="1"
         android:layout_height="wrap_content"
-        android:gravity="center_vertical"
-        android:orientation="vertical"
-        android:minHeight="@dimen/detail_min_line_item_height">
+        android:orientation="horizontal"
+        android:layout_gravity="center_vertical"
+        android:focusable="true"
+        android:background="?android:attr/selectableItemBackground">
 
         <LinearLayout
-            android:layout_width="match_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_gravity="center_vertical">
+            android:layout_gravity="center_vertical"
+            android:layout_weight="1"
+            android:paddingLeft="12dip"
+            android:orientation="vertical">
 
-            <FrameLayout
-                android:layout_width="@dimen/detail_item_type_width"
-                android:layout_height="@dimen/detail_min_line_item_height"
-                android:paddingLeft="@dimen/detail_item_side_margin">
+            <TextView
+                android:id="@+id/data"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium" />
 
-                <TextView
-                    android:id="@+id/kind"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:visibility="gone" />
+            <TextView
+                android:id="@+id/footer"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:visibility="gone" />
 
-                <LinearLayout
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:orientation="horizontal">
+        </LinearLayout>
 
-                    <TextView
-                        android:id="@+id/type"
-                        style="@style/ContactDetailItemType" />
+        <ImageView
+            android:id="@+id/presence_icon"
+            android:layout_width="32dip"
+            android:layout_height="@dimen/detail_min_line_item_height"
+            android:layout_marginLeft="5dip"
+            android:gravity="center"
+            android:scaleType="centerInside" />
 
-                    <View
-                        android:id="@+id/primary_indicator"
-                        android:layout_width="16dip"
-                        android:layout_height="16dip"
-                        android:visibility="gone"
-                        android:layout_gravity="center_vertical"
-                        android:background="@drawable/ic_menu_mark" />
+        <FrameLayout
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/detail_min_line_item_height"
+            android:paddingLeft="@dimen/detail_item_side_margin"
+            android:paddingRight="@dimen/detail_item_side_margin">
 
-                </LinearLayout>
-
-            </FrameLayout>
+            <TextView
+                android:id="@+id/kind"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:visibility="gone" />
 
             <LinearLayout
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:layout_weight="1"
-                android:paddingLeft="12dip"
-                android:orientation="vertical">
+                android:layout_height="match_parent"
+                android:orientation="horizontal">
 
                 <TextView
-                    android:id="@+id/data"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:textAppearance="?android:attr/textAppearanceMedium" />
+                    android:id="@+id/type"
+                    style="@style/ContactDetailItemType" />
 
-                <TextView
-                    android:id="@+id/footer"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:textAppearance="?android:attr/textAppearanceSmall"
-                    android:visibility="gone" />
+                <View
+                    android:id="@+id/primary_indicator"
+                    android:layout_width="16dip"
+                    android:layout_height="16dip"
+                    android:visibility="gone"
+                    android:layout_gravity="center_vertical"
+                    android:background="@drawable/ic_menu_mark" />
 
             </LinearLayout>
+        </FrameLayout>
+    </com.android.contacts.detail.PrimaryActionViewContainer>
 
-            <ImageView
-                android:id="@+id/presence_icon"
-                android:layout_width="32dip"
-                android:layout_height="@dimen/detail_min_line_item_height"
-                android:layout_marginLeft="5dip"
-                android:gravity="center"
-                android:scaleType="centerInside" />
+    <View
+        android:id="@+id/vertical_divider"
+        android:layout_width="1px"
+        android:layout_height="match_parent"
+        android:layout_marginTop="@dimen/detail_vertical_divider_vertical_margin"
+        android:layout_marginBottom="@dimen/detail_vertical_divider_vertical_margin"
+        android:background="?android:attr/dividerVertical" />
 
-            <View
-                android:id="@+id/vertical_divider"
-                android:layout_width="1px"
-                android:layout_height="match_parent"
-                android:layout_marginTop="5dip"
-                android:layout_marginBottom="5dip"
-                android:layout_marginLeft="14dip"
-                android:layout_marginRight="14dip"
-                android:background="?android:attr/dividerVertical" />
-
-            <FrameLayout
-                android:id="@+id/secondary_action_button_container"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_marginTop="10dip"
-                android:paddingLeft="@dimen/detail_item_icon_margin"
-                android:paddingRight="@dimen/detail_item_icon_margin"
-                android:duplicateParentState="false"
-                android:background="?android:attr/selectableItemBackground">
-
-                <ImageView
-                    android:id="@+id/secondary_action_button"
-                    android:layout_width="32dip"
-                    android:layout_height="match_parent"
-                    android:layout_centerVertical="true"
-                    android:gravity="center"
-                    android:scaleType="center"
-                    android:duplicateParentState="false" />
-
-             </FrameLayout>
-        </LinearLayout>
-
-    </LinearLayout>
-
+    <!-- Note: padding might be controlled programatically -->
+    <FrameLayout
+        android:id="@+id/secondary_action_view_container"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:paddingLeft="@dimen/detail_item_icon_margin"
+        android:paddingRight="@dimen/detail_item_icon_margin"
+        android:duplicateParentState="false"
+        android:focusable="true"
+        android:background="?android:attr/selectableItemBackground">
+        <ImageView
+            android:id="@+id/secondary_action_button"
+            android:layout_width="32dip"
+            android:layout_height="match_parent"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:scaleType="center"
+            android:duplicateParentState="false" />
+    </FrameLayout>
 </LinearLayout>
diff --git a/res/layout/contact_detail_list_item.xml b/res/layout/contact_detail_list_item.xml
index e96b7f0..205bc81 100644
--- a/res/layout/contact_detail_list_item.xml
+++ b/res/layout/contact_detail_list_item.xml
@@ -17,86 +17,100 @@
  */
 -->
 
+<!-- Note: padding might be controlled programatically -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
-    android:gravity="center_vertical">
+    android:gravity="center_vertical"
+    android:minHeight="@dimen/detail_min_line_item_height">
 
-    <LinearLayout
+    <!-- Note: padding might be controlled programatically -->
+    <com.android.contacts.detail.PrimaryActionViewContainer
+        android:id="@+id/primary_action_view_container"
         android:layout_width="0dip"
-        android:layout_height="wrap_content"
         android:layout_weight="1"
-        android:orientation="vertical"
-        android:paddingLeft="8dip"
-        android:gravity="center_vertical">
-
-        <TextView
-            android:id="@+id/kind"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:visibility="gone" />
-
-        <TextView
-            android:id="@+id/data"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:textAppearance="?android:attr/textAppearanceMedium" />
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:focusable="true"
+        android:background="?android:attr/selectableItemBackground">
 
         <LinearLayout
-            android:layout_width="wrap_content"
+            android:layout_width="0dip"
             android:layout_height="wrap_content"
-            android:orientation="horizontal">
+            android:layout_weight="1"
+            android:orientation="vertical"
+            android:paddingLeft="8dip"
+            android:gravity="center_vertical">
 
             <TextView
-                android:id="@+id/type"
-                style="@style/ContactDetailItemType" />
+                android:id="@+id/kind"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:visibility="gone" />
 
-            <View
-                android:id="@+id/primary_indicator"
-                android:layout_width="16dip"
-                android:layout_height="16dip"
-                android:visibility="gone"
+            <TextView
+                android:id="@+id/data"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
                 android:layout_gravity="center_vertical"
-                android:background="@drawable/ic_menu_mark" />
+                android:textAppearance="?android:attr/textAppearanceMedium" />
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+
+                <TextView
+                    android:id="@+id/type"
+                    style="@style/ContactDetailItemType" />
+
+                <View
+                    android:id="@+id/primary_indicator"
+                    android:layout_width="16dip"
+                    android:layout_height="16dip"
+                    android:visibility="gone"
+                    android:layout_gravity="center_vertical"
+                    android:background="@drawable/ic_menu_mark" />
+
+            </LinearLayout>
+
+            <TextView
+                android:id="@+id/footer"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:visibility="gone" />
 
         </LinearLayout>
 
-        <TextView
-            android:id="@+id/footer"
-            android:layout_width="wrap_content"
+        <ImageView
+            android:id="@+id/presence_icon"
+            android:layout_width="32dip"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:visibility="gone" />
-
-    </LinearLayout>
-
-    <ImageView
-        android:id="@+id/presence_icon"
-        android:layout_width="32dip"
-        android:layout_height="wrap_content"
-        android:layout_marginLeft="5dip"
-        android:gravity="center"
-        android:scaleType="centerInside" />
+            android:layout_marginLeft="5dip"
+            android:gravity="center"
+            android:scaleType="centerInside" />
+    </com.android.contacts.detail.PrimaryActionViewContainer>
 
     <View
         android:id="@+id/vertical_divider"
         android:layout_width="1dip"
         android:layout_height="match_parent"
-        android:layout_marginTop="4dip"
-        android:layout_marginBottom="4dip"
+        android:layout_marginTop="@dimen/detail_vertical_divider_vertical_margin"
+        android:layout_marginBottom="@dimen/detail_vertical_divider_vertical_margin"
         android:background="?android:attr/dividerVertical" />
 
+    <!-- Note: padding might be controlled programatically -->
     <FrameLayout
-        android:id="@+id/secondary_action_button_container"
+        android:id="@+id/secondary_action_view_container"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:paddingLeft="@dimen/detail_item_icon_margin"
         android:paddingRight="@dimen/detail_item_icon_margin"
-        android:duplicateParentState="false"
+        android:focusable="true"
         android:background="?android:attr/selectableItemBackground">
         <ImageView
             android:id="@+id/secondary_action_button"
diff --git a/res/layout/quickcontact_list_item.xml b/res/layout/quickcontact_list_item.xml
index 14d8720..4ffa091 100755
--- a/res/layout/quickcontact_list_item.xml
+++ b/res/layout/quickcontact_list_item.xml
@@ -20,16 +20,18 @@
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:background="@drawable/quickcontact_list_item_background"
-    android:minHeight="?android:attr/listPreferredItemHeight"
     android:gravity="center_vertical">
     <LinearLayout
+        android:id="@+id/primary_action_view_container"
         android:layout_width="0dip"
         android:layout_height="wrap_content"
+        android:minHeight="?android:attr/listPreferredItemHeight"
         android:layout_weight="1"
         android:orientation="vertical"
         android:paddingLeft="16dip"
         android:paddingRight="16dip"
-        android:gravity="center_vertical">
+        android:gravity="center_vertical"
+        android:background="?android:attr/selectableItemBackground">
         <TextView
             android:id="@android:id/text1"
             android:layout_width="wrap_content"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 69c89d8..cbac941 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -133,15 +133,16 @@
     <!-- Minimum height of a row in the contact detail -->
     <dimen name="detail_min_line_item_height">48dip</dimen>
 
-    <!-- Width of a contact detail item type (i.e. Nickname or Website). -->
-    <dimen name="detail_item_type_width">164dip</dimen>
-
     <!-- Width of height of an icon from a third-party app in the networks section of the contact card. -->
     <dimen name="detail_network_icon_size">32dip</dimen>
 
     <!-- Font size for the display name in header of the contact detail page -->
     <dimen name="detail_header_name_text_size">36sp</dimen>
 
+    <!-- Vertical margin for vertical dividers existing between primary data
+         (phone number, email, etc.) and a secondary action button -->
+    <dimen name="detail_vertical_divider_vertical_margin">16dip</dimen>
+
     <!-- Padding to be used between a visible scrollbar and the contact list -->
     <dimen name="list_visible_scrollbar_padding">40dip</dimen>
 
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 946fbe8..c3b2de6 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -117,7 +117,7 @@
 import java.util.Map;
 
 public class ContactDetailFragment extends Fragment implements FragmentKeyListener, ViewOverlay,
-        OnItemClickListener, SelectAccountDialogFragment.Listener {
+        SelectAccountDialogFragment.Listener {
 
     private static final String TAG = "ContactDetailFragment";
 
@@ -264,8 +264,7 @@
 
         mListView = (ListView) mView.findViewById(android.R.id.list);
         mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
-        mListView.setOnItemClickListener(this);
-        registerForContextMenu(mListView);
+        mListView.setItemsCanFocus(true);
         mListView.setOnScrollListener(mVerticalScrollListener);
 
         // Don't set it to mListView yet.  We do so later when we bind the adapter.
@@ -1331,29 +1330,37 @@
      * {@link DetailViewEntry}
      */
     private static class DetailViewCache {
-        public TextView kind;
-        public TextView type;
-        public TextView data;
-        public TextView footer;
-        public ImageView presenceIcon;
-        public ImageView secondaryActionButton;
-        public View secondaryActionButtonContainer;
-        public View secondaryActionDivider;
-        public View primaryIndicator;
+        public final TextView kind;
+        public final TextView type;
+        public final TextView data;
+        public final TextView footer;
+        public final ImageView presenceIcon;
+        public final ImageView secondaryActionButton;
+        public final View primaryActionViewContainer;
+        public final View secondaryActionViewContainer;
+        public final View secondaryActionDivider;
+        public final View primaryIndicator;
 
-        public DetailViewCache(View view, OnClickListener secondaryActionClickListener) {
+        public DetailViewCache(View view,
+                OnClickListener primaryActionClickListener,
+                OnClickListener secondaryActionClickListener) {
             kind = (TextView) view.findViewById(R.id.kind);
             type = (TextView) view.findViewById(R.id.type);
             data = (TextView) view.findViewById(R.id.data);
             footer = (TextView) view.findViewById(R.id.footer);
             primaryIndicator = view.findViewById(R.id.primary_indicator);
             presenceIcon = (ImageView) view.findViewById(R.id.presence_icon);
+
+            primaryActionViewContainer = view.findViewById(R.id.primary_action_view_container);
+            primaryActionViewContainer.setOnClickListener(primaryActionClickListener);
+
+            secondaryActionViewContainer = view.findViewById(
+                    R.id.secondary_action_view_container);
+            secondaryActionViewContainer.setOnClickListener(
+                    secondaryActionClickListener);
             secondaryActionButton = (ImageView) view.findViewById(
                     R.id.secondary_action_button);
-            secondaryActionButtonContainer = view.findViewById(
-                    R.id.secondary_action_button_container);
-            secondaryActionButtonContainer.setOnClickListener(
-                    secondaryActionClickListener);
+
             secondaryActionDivider = view.findViewById(R.id.vertical_divider);
         }
     }
@@ -1494,15 +1501,16 @@
                 v = mInflater.inflate(R.layout.contact_detail_list_item, parent, false);
 
                 // Cache the children
-                viewCache = new DetailViewCache(v, mSecondaryActionClickListener);
+                viewCache = new DetailViewCache(v,
+                        mPrimaryActionClickListener, mSecondaryActionClickListener);
                 v.setTag(viewCache);
             }
 
-            bindDetailView(v, entry);
+            bindDetailView(position, v, entry);
             return v;
         }
 
-        private void bindDetailView(View view, DetailViewEntry entry) {
+        private void bindDetailView(int position, View view, DetailViewEntry entry) {
             final Resources resources = mContext.getResources();
             DetailViewCache views = (DetailViewCache) view.getTag();
 
@@ -1538,6 +1546,12 @@
                 presenceIconView.setVisibility(View.GONE);
             }
 
+            final PrimaryActionViewContainer primaryActionButtonContainer =
+                    (PrimaryActionViewContainer) views.primaryActionViewContainer;
+            primaryActionButtonContainer.setTag(entry);
+            primaryActionButtonContainer.setPosition(position);
+            registerForContextMenu(primaryActionButtonContainer);
+
             // Set the secondary action button
             final ImageView secondaryActionView = views.secondaryActionButton;
             Drawable secondaryActionIcon = null;
@@ -1551,20 +1565,30 @@
                         resources.getDrawable(R.drawable.sym_action_audiochat_holo_light);
             }
 
+            final View secondaryActionViewContainer = views.secondaryActionViewContainer;
             if (entry.secondaryIntent != null && secondaryActionIcon != null) {
                 secondaryActionView.setImageDrawable(secondaryActionIcon);
-                views.secondaryActionButtonContainer.setTag(entry);
-                views.secondaryActionButtonContainer.setVisibility(View.VISIBLE);
+                secondaryActionViewContainer.setTag(entry);
+                secondaryActionViewContainer.setVisibility(View.VISIBLE);
                 views.secondaryActionDivider.setVisibility(View.VISIBLE);
             } else {
-                views.secondaryActionButtonContainer.setVisibility(View.GONE);
+                secondaryActionViewContainer.setVisibility(View.GONE);
                 views.secondaryActionDivider.setVisibility(View.GONE);
             }
 
-            view.setPadding(entry.isInSubSection() ? mViewEntryDimensions.getWidePaddingLeft() :
-                    mViewEntryDimensions.getPaddingLeft(),
+            // Right padding should not have "pressed" effect.
+            view.setPadding(0, 0, mViewEntryDimensions.getPaddingRight(), 0);
+            // Top, left, and bottom paddings should have "pressed" effect.
+            primaryActionButtonContainer.setPadding(entry.isInSubSection() ?
+                    mViewEntryDimensions.getWidePaddingLeft() :
+                            mViewEntryDimensions.getPaddingLeft(),
                     mViewEntryDimensions.getPaddingTop(),
-                    mViewEntryDimensions.getPaddingRight(),
+                    0,
+                    mViewEntryDimensions.getPaddingBottom());
+            secondaryActionViewContainer.setPadding(
+                    secondaryActionViewContainer.getPaddingLeft(),
+                    mViewEntryDimensions.getPaddingTop(),
+                    secondaryActionViewContainer.getPaddingRight(),
                     mViewEntryDimensions.getPaddingBottom());
         }
 
@@ -1579,12 +1603,22 @@
             }
         }
 
-        private OnClickListener mSecondaryActionClickListener = new OnClickListener() {
+        private final OnClickListener mPrimaryActionClickListener = new OnClickListener() {
             @Override
-            public void onClick(View v) {
+            public void onClick(View view) {
                 if (mListener == null) return;
-                if (v == null) return;
-                final ViewEntry entry = (ViewEntry) v.getTag();
+                final ViewEntry entry = (ViewEntry) view.getTag();
+                if (entry == null) return;
+                entry.click(view, mListener);
+            }
+        };
+
+        private final OnClickListener mSecondaryActionClickListener = new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                if (mListener == null) return;
+                if (view == null) return;
+                final ViewEntry entry = (ViewEntry) view.getTag();
                 if (entry == null || !(entry instanceof DetailViewEntry)) return;
                 final DetailViewEntry detailViewEntry = (DetailViewEntry) entry;
                 final Intent intent = detailViewEntry.secondaryIntent;
@@ -1650,14 +1684,6 @@
     }
 
     @Override
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        if (mListener == null) return;
-        final ViewEntry entry = mAdapter.getItem(position);
-        if (entry == null) return;
-        entry.click(view, mListener);
-    }
-
-    @Override
     public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
         super.onCreateContextMenu(menu, view, menuInfo);
 
diff --git a/src/com/android/contacts/detail/PrimaryActionViewContainer.java b/src/com/android/contacts/detail/PrimaryActionViewContainer.java
new file mode 100644
index 0000000..a342884
--- /dev/null
+++ b/src/com/android/contacts/detail/PrimaryActionViewContainer.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 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.contacts.detail;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+
+/**
+ * Custom {@link LinearLayout} which remembers its position in the {@link ListView}. Should be
+ * used for primary touch targets in {@link ContactDetailFragment}.
+ */
+/* package */ class PrimaryActionViewContainer extends LinearLayout {
+
+    private ContextMenuInfo mContextMenuInfo;
+
+    public PrimaryActionViewContainer(Context context) {
+        super(context);
+    }
+
+    public PrimaryActionViewContainer(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public PrimaryActionViewContainer(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public void setPosition(int position) {
+        mContextMenuInfo = new AdapterView.AdapterContextMenuInfo(this, position, -1);
+    }
+
+    @Override
+    public ContextMenuInfo getContextMenuInfo() {
+        return mContextMenuInfo;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/contacts/quickcontact/QuickContactListFragment.java b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
index 18c6ef5..1c36ae1 100644
--- a/src/com/android/contacts/quickcontact/QuickContactListFragment.java
+++ b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
@@ -50,7 +50,8 @@
         mFragmentContainer = (LinearLayout) inflater.inflate(R.layout.quickcontact_list_fragment,
                 container, false);
         mListView = (ListView) mFragmentContainer.findViewById(R.id.list);
-        mListView.setOnItemClickListener(mItemClickListener);
+        mListView.setItemsCanFocus(true);
+
         mFragmentContainer.setOnClickListener(mOutsideClickListener);
         configureAdapter();
         return mFragmentContainer;
@@ -98,10 +99,14 @@
                         android.R.id.text1);
                 final TextView text2 = (TextView) resultView.findViewById(
                         android.R.id.text2);
+                final View primaryActionContainer = resultView.findViewById(
+                        R.id.primary_action_view_container);
                 final ImageView alternateActionButton = (ImageView) resultView.findViewById(
                         R.id.secondary_action_button);
                 final View alternateActionDivider = resultView.findViewById(R.id.vertical_divider);
 
+                primaryActionContainer.setOnClickListener(mPrimaryActionClickListener);
+                primaryActionContainer.setTag(action);
                 alternateActionButton.setOnClickListener(mSecondaryActionClickListener);
                 alternateActionButton.setTag(action);
 
@@ -112,12 +117,20 @@
                 text1.setText(action.getBody());
                 text2.setText(action.getSubtitle());
 
-                resultView.setTag(action);
                 return resultView;
             }
         });
     }
 
+    /** A data item (e.g. phone number) was clicked */
+    protected final OnClickListener mPrimaryActionClickListener = new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            final Action action = (Action) v.getTag();
+            if (mListener != null) mListener.onItemClicked(action, false);
+        }
+    };
+
     /** A secondary action (SMS) was clicked */
     protected final OnClickListener mSecondaryActionClickListener = new OnClickListener() {
         @Override
@@ -127,16 +140,6 @@
         }
     };
 
-    /** A data item (e.g. phone number) was clicked */
-    private final AbsListView.OnItemClickListener mItemClickListener =
-            new AbsListView.OnItemClickListener() {
-        @Override
-        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            final Action action = (Action) view.getTag();
-            if (mListener != null) mListener.onItemClicked(action, false);
-        }
-    };
-
     private final OnClickListener mOutsideClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {