Add ExpandingEntryCardView to QuickContact
The communication card is slightly implemented to make sure ExpandingEntryCardView
works as intended. There is more work to do in a different CL to finish this.
Also delete a bunch of QC code.
Change-Id: If7d8373866560c635851fe0e09ffad9cc0054f4f
diff --git a/res/drawable-hdpi/expanding_entry_card_expand_white_24.png b/res/drawable-hdpi/expanding_entry_card_expand_white_24.png
new file mode 100644
index 0000000..50ebbc5
--- /dev/null
+++ b/res/drawable-hdpi/expanding_entry_card_expand_white_24.png
Binary files differ
diff --git a/res/drawable-mdpi/expanding_entry_card_expand_white_24.png b/res/drawable-mdpi/expanding_entry_card_expand_white_24.png
new file mode 100644
index 0000000..a0d4063
--- /dev/null
+++ b/res/drawable-mdpi/expanding_entry_card_expand_white_24.png
Binary files differ
diff --git a/res/drawable-xhdpi/expanding_entry_card_expand_white_24.png b/res/drawable-xhdpi/expanding_entry_card_expand_white_24.png
new file mode 100644
index 0000000..42e9f2c
--- /dev/null
+++ b/res/drawable-xhdpi/expanding_entry_card_expand_white_24.png
Binary files differ
diff --git a/res/drawable-xxhdpi/expanding_entry_card_expand_white_24.png b/res/drawable-xxhdpi/expanding_entry_card_expand_white_24.png
new file mode 100644
index 0000000..af4d711
--- /dev/null
+++ b/res/drawable-xxhdpi/expanding_entry_card_expand_white_24.png
Binary files differ
diff --git a/res/drawable/quickcontact_track_background.xml b/res/drawable/expanding_entry_card_collapse_white_24.xml
similarity index 70%
rename from res/drawable/quickcontact_track_background.xml
rename to res/drawable/expanding_entry_card_collapse_white_24.xml
index fcf61fd..a38706e 100644
--- a/res/drawable/quickcontact_track_background.xml
+++ b/res/drawable/expanding_entry_card_collapse_white_24.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2014 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.
@@ -14,6 +14,7 @@
limitations under the License.
-->
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/quickcon_background_texture"
- android:tileMode="repeat" />
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/expanding_entry_card_expand_white_24"
+ android:fromDegrees="180"
+ android:toDegrees="0"/>
\ No newline at end of file
diff --git a/res/drawable/list_divider.xml b/res/drawable/list_divider.xml
deleted file mode 100644
index 81df0f5..0000000
--- a/res/drawable/list_divider.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid
- android:color="@color/quickcontact_list_divider"/>
-</shape>
\ No newline at end of file
diff --git a/res/drawable/quickcontact_list_item_divider.xml b/res/drawable/quickcontact_list_item_divider.xml
deleted file mode 100644
index 99882c4..0000000
--- a/res/drawable/quickcontact_list_item_divider.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/list_divider"
- android:insetRight="16dp"
- android:insetLeft="16dp" />
\ No newline at end of file
diff --git a/res/layout-land/quickcontact_activity.xml b/res/layout-land/quickcontact_activity.xml
index c398551..6b85eae 100644
--- a/res/layout-land/quickcontact_activity.xml
+++ b/res/layout-land/quickcontact_activity.xml
@@ -13,45 +13,26 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<view
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ex="http://schemas.android.com/apk/res-auto"
- class="com.android.contacts.quickcontact.FloatingChildLayout"
- android:id="@+id/floating_layout"
+ android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="afterDescendants">
- <LinearLayout
- android:id="@android:id/content"
- android:layout_width="match_parent"
+ android:padding="32dip"
+ android:orientation="horizontal">
+ <view
+ class="com.android.contacts.common.widget.ProportionalLayout"
+ android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:padding="32dip"
- android:orientation="horizontal">
- <view
- class="com.android.contacts.common.widget.ProportionalLayout"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- ex:ratio="1.0"
- ex:direction="heightToWidth">
- <include layout="@layout/quickcontact_photo_container" />
- </view>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <include layout="@layout/quickcontact_track" />
- <View
- android:id="@+id/line_after_track"
- android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="@color/quickcontact_tab_indicator" />
- <android.support.v4.view.ViewPager
- android:id="@+id/item_list_pager"
- android:background="@drawable/quickcontact_track_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </LinearLayout>
- </LinearLayout>
-</view>
+ ex:ratio="1.0"
+ ex:direction="heightToWidth">
+ <include layout="@layout/quickcontact_photo_container" />
+ </view>
+ <com.android.contacts.quickcontact.ExpandingEntryCardView
+ android:id="@+id/communication_card"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:background="@color/quickcontact_activity_background" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout-sw600dp-land/quickcontact_activity.xml b/res/layout-sw600dp-land/quickcontact_activity.xml
index 230c4e0..563ca43 100644
--- a/res/layout-sw600dp-land/quickcontact_activity.xml
+++ b/res/layout-sw600dp-land/quickcontact_activity.xml
@@ -13,41 +13,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<view
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- class="com.android.contacts.quickcontact.FloatingChildLayout"
- android:id="@+id/floating_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="afterDescendants">
- <LinearLayout
- android:id="@android:id/content"
- android:layout_width="wrap_content"
+ android:id="@android:id/content"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="32dip"
+ android:orientation="horizontal">
+ <FrameLayout
+ android:layout_width="360dip"
+ android:layout_height="360dip">
+ <include layout="@layout/quickcontact_photo_container" />
+ </FrameLayout>
+ <com.android.contacts.quickcontact.ExpandingEntryCardView
+ android:id="@+id/communication_card"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="32dip"
- android:orientation="horizontal">
- <FrameLayout
- android:layout_width="360dip"
- android:layout_height="360dip">
- <include layout="@layout/quickcontact_photo_container" />
- </FrameLayout>
- <LinearLayout
- android:layout_width="360dip"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <include layout="@layout/quickcontact_track" />
- <View
- android:id="@+id/line_after_track"
- android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="@color/quickcontact_tab_indicator" />
- <android.support.v4.view.ViewPager
- android:id="@+id/item_list_pager"
- android:background="@drawable/quickcontact_track_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </LinearLayout>
- </LinearLayout>
-</view>
+ android:orientation="vertical"
+ android:background="@color/quickcontact_activity_background" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout-sw600dp/quickcontact_activity.xml b/res/layout-sw600dp/quickcontact_activity.xml
index 229974b..686212d 100644
--- a/res/layout-sw600dp/quickcontact_activity.xml
+++ b/res/layout-sw600dp/quickcontact_activity.xml
@@ -13,37 +13,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<view
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res-auto"
- class="com.android.contacts.quickcontact.FloatingChildLayout"
- android:id="@+id/floating_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="afterDescendants">
- <LinearLayout
- android:id="@android:id/content"
- android:layout_width="wrap_content"
+ android:id="@android:id/content"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="32dip"
+ android:orientation="vertical" >
+ <FrameLayout
+ android:layout_width="360dip"
+ android:layout_height="@dimen/quick_contact_photo_container_height">
+ <include layout="@layout/quickcontact_photo_container" />
+ </FrameLayout>
+ <com.android.contacts.quickcontact.ExpandingEntryCardView
+ android:id="@+id/communication_card"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="32dip"
- android:orientation="vertical" >
- <FrameLayout
- android:layout_width="360dip"
- android:layout_height="@dimen/quick_contact_photo_container_height">
- <include layout="@layout/quickcontact_photo_container" />
- </FrameLayout>
- <include layout="@layout/quickcontact_track" />
- <View
- android:id="@+id/line_after_track"
- android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="@color/quickcontact_tab_indicator" />
- <android.support.v4.view.ViewPager
- android:id="@+id/item_list_pager"
- android:background="@drawable/quickcontact_track_background"
- android:layout_width="match_parent"
- android:layout_height="160dip" />
- </LinearLayout>
-</view>
+ android:orientation="vertical"
+ android:background="@color/quickcontact_activity_background" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout-sw720dp-land/quickcontact_activity.xml b/res/layout-sw720dp-land/quickcontact_activity.xml
index 230c4e0..563ca43 100644
--- a/res/layout-sw720dp-land/quickcontact_activity.xml
+++ b/res/layout-sw720dp-land/quickcontact_activity.xml
@@ -13,41 +13,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<view
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- class="com.android.contacts.quickcontact.FloatingChildLayout"
- android:id="@+id/floating_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="afterDescendants">
- <LinearLayout
- android:id="@android:id/content"
- android:layout_width="wrap_content"
+ android:id="@android:id/content"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="32dip"
+ android:orientation="horizontal">
+ <FrameLayout
+ android:layout_width="360dip"
+ android:layout_height="360dip">
+ <include layout="@layout/quickcontact_photo_container" />
+ </FrameLayout>
+ <com.android.contacts.quickcontact.ExpandingEntryCardView
+ android:id="@+id/communication_card"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="32dip"
- android:orientation="horizontal">
- <FrameLayout
- android:layout_width="360dip"
- android:layout_height="360dip">
- <include layout="@layout/quickcontact_photo_container" />
- </FrameLayout>
- <LinearLayout
- android:layout_width="360dip"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <include layout="@layout/quickcontact_track" />
- <View
- android:id="@+id/line_after_track"
- android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="@color/quickcontact_tab_indicator" />
- <android.support.v4.view.ViewPager
- android:id="@+id/item_list_pager"
- android:background="@drawable/quickcontact_track_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </LinearLayout>
- </LinearLayout>
-</view>
+ android:orientation="vertical"
+ android:background="@color/quickcontact_activity_background" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/expanding_entry_card_item.xml b/res/layout/expanding_entry_card_item.xml
new file mode 100644
index 0000000..5f2deeb
--- /dev/null
+++ b/res/layout/expanding_entry_card_item.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <RelativeLayout
+ style="@style/SelectableItem"
+ android:id="@+id/entry_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingLeft="@dimen/expanding_entry_card_item_padding_with_image_start"
+ android:paddingRight="@dimen/expanding_entry_card_item_padding_end"
+ android:paddingTop="@dimen/expanding_entry_card_item_padding_top"
+ android:paddingBottom="@dimen/expanding_entry_card_item_padding_bottom">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/icon"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginRight="@dimen/expanding_entry_card_item_image_spacing"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/header"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@+id/icon"
+ android:textStyle="bold"
+ android:textColor="@android:color/black"
+ android:singleLine="true"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/sub_header"
+ android:layout_below="@+id/header"
+ android:layout_toRightOf="@+id/icon_sub_header"
+ android:textColor="@android:color/black"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/icon_sub_header"
+ android:layout_below="@+id/header"
+ android:layout_toRightOf="@+id/icon"
+ android:layout_marginRight="@dimen/expanding_entry_card_item_sub_header_icon_margin_right"
+ android:layout_marginBottom="@dimen/expanding_entry_card_item_sub_header_icon_margin_bottom" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/text"
+ android:layout_below="@+id/sub_header"
+ android:layout_toRightOf="@+id/icon_text"
+ android:textColor="@android:color/darker_gray"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/icon_text"
+ android:layout_toRightOf="@+id/icon"
+ android:layout_below="@+id/sub_header"
+ android:layout_marginTop="@dimen/expanding_entry_card_item_text_icon_margin_top"
+ android:layout_marginRight="@dimen/expanding_entry_card_item_text_icon_margin_right" />
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/res/layout/expanding_entry_card_view.xml b/res/layout/expanding_entry_card_view.xml
new file mode 100644
index 0000000..12f96e6
--- /dev/null
+++ b/res/layout/expanding_entry_card_view.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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">
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:lines="1"
+ android:padding="@dimen/expanding_entry_card_title_padding"
+ android:singleLine="true"
+ android:textSize="@dimen/expanding_entry_card_title_text_size" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/expanding_entry_card_item_separator_height"
+ android:background="@color/expanding_entry_card_item_separator_color" />
+
+ <LinearLayout
+ android:id="@+id/content_area_linear_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+
+</merge>
\ No newline at end of file
diff --git a/res/layout/quickcontact_activity.xml b/res/layout/quickcontact_activity.xml
index 36bdd50..3aa0a14 100644
--- a/res/layout/quickcontact_activity.xml
+++ b/res/layout/quickcontact_activity.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!--
+ 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.
@@ -13,44 +14,37 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<view
- xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ex="http://schemas.android.com/apk/res-auto"
- class="com.android.contacts.quickcontact.FloatingChildLayout"
- android:id="@+id/floating_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true"
- android:descendantFocusability="afterDescendants">
+ android:descendantFocusability="afterDescendants" >
+
<LinearLayout
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="15dip"
- android:paddingRight="15dip"
- android:paddingStart="15dip"
- android:paddingEnd="15dip"
- android:paddingTop="8dip"
- android:orientation="vertical">
+ android:orientation="vertical" >
+
<view
- class="com.android.contacts.common.widget.ProportionalLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- ex:ratio="0.5"
- ex:direction="widthToHeight">
+ class="com.android.contacts.common.widget.ProportionalLayout"
+ ex:direction="widthToHeight"
+ ex:ratio="0.5" >
+
<include layout="@layout/quickcontact_photo_container" />
</view>
- <include layout="@layout/quickcontact_track" />
- <View
- android:id="@+id/line_after_track"
+
+ <com.android.contacts.quickcontact.ExpandingEntryCardView
+ android:id="@+id/communication_card"
android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="@color/quickcontact_tab_indicator" />
- <android.support.v4.view.ViewPager
- android:id="@+id/item_list_pager"
- android:layout_width="match_parent"
- android:layout_height="156dip"
- android:background="@color/quickcontact_activity_background"/>
+ android:layout_height="wrap_content"
+ android:background="@color/quickcontact_activity_background"
+ android:orientation="vertical" />
</LinearLayout>
-</view>
+
+</ScrollView>
\ No newline at end of file
diff --git a/res/layout/quickcontact_expanding_entry_card_button.xml b/res/layout/quickcontact_expanding_entry_card_button.xml
new file mode 100644
index 0000000..9cd34d7
--- /dev/null
+++ b/res/layout/quickcontact_expanding_entry_card_button.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ style="@style/SelectableItem" >
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/expanding_entry_card_item_separator_height"
+ android:background="@color/expanding_entry_card_item_separator_color" />
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:drawablePadding="@dimen/expanding_entry_card_button_drawable_padding"
+ android:gravity="center_vertical"
+ android:paddingBottom="@dimen/expanding_entry_card_button_padding_vertical"
+ android:paddingLeft="@dimen/expanding_entry_card_button_padding_start"
+ android:paddingTop="@dimen/expanding_entry_card_button_padding_vertical"
+ android:textColor="@color/expanding_entry_card_button_text_color" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/quickcontact_list_fragment.xml b/res/layout/quickcontact_list_fragment.xml
deleted file mode 100755
index 712f116..0000000
--- a/res/layout/quickcontact_list_fragment.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <ListView
- android:id="@+id/list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:divider="@drawable/quickcontact_list_item_divider"
- android:dividerHeight="1dip"
- android:background="@color/quickcontact_list_background"
- android:cacheColorHint="@null"
- android:layout_alignParentTop="true"
- />
- <View
- android:layout_alignBottom="@+id/list"
- style="@style/QuickContactListBottomStyle"/>
-</RelativeLayout>
diff --git a/res/layout/quickcontact_list_item.xml b/res/layout/quickcontact_list_item.xml
deleted file mode 100755
index 615895f..0000000
--- a/res/layout/quickcontact_list_item.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/actions_view_container"
- android:nextFocusRight="@+id/secondary_action_button"
- style="@style/QuickContactListItemStyle">
- <LinearLayout style="@style/QuickContactListItemTextWrapperStyle">
- <TextView
- android:id="@android:id/text1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@color/primary_text_color"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:singleLine="true"
- android:ellipsize="end" />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <ImageView
- android:id="@+id/presence_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="1dip"
- android:layout_marginRight="4dip"
- android:layout_marginEnd="4dip"
- android:layout_gravity="center_vertical"
- android:gravity="center"
- android:scaleType="centerInside" />
- <TextView
- android:id="@android:id/text2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@color/secondary_text_color"
- android:textAllCaps="true"
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </LinearLayout>
- </LinearLayout>
- <include layout="@layout/quickcontact_list_item_base"/>
-</LinearLayout>
diff --git a/res/layout/quickcontact_list_item_address.xml b/res/layout/quickcontact_list_item_address.xml
deleted file mode 100755
index c55c339..0000000
--- a/res/layout/quickcontact_list_item_address.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/actions_view_container"
- android:nextFocusRight="@+id/secondary_action_button"
- style="@style/QuickContactListItemStyle">
- <LinearLayout style="@style/QuickContactListItemTextWrapperStyle"
- android:layout_marginTop="12dip"
- android:layout_marginBottom="12dip">
- <TextView
- android:id="@android:id/text1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@color/primary_text_color"
- android:textAppearance="?android:attr/textAppearanceMedium" />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <ImageView
- android:id="@+id/presence_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="1dip"
- android:layout_marginRight="4dip"
- android:layout_marginEnd="4dip"
- android:layout_gravity="center_vertical"
- android:gravity="center"
- android:scaleType="centerInside" />
- <TextView
- android:id="@android:id/text2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@color/secondary_text_color"
- android:textAllCaps="true"
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </LinearLayout>
- </LinearLayout>
- <include layout="@layout/quickcontact_list_item_base"/>
-</LinearLayout>
diff --git a/res/layout/quickcontact_list_item_base.xml b/res/layout/quickcontact_list_item_base.xml
deleted file mode 100644
index 80a3422..0000000
--- a/res/layout/quickcontact_list_item_base.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <View
- android:id="@+id/vertical_divider"
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:layout_marginTop="@dimen/detail_vertical_divider_vertical_margin"
- android:layout_marginBottom="@dimen/detail_vertical_divider_vertical_margin"
- android:background="?android:attr/dividerVertical" />
- <ImageView
- android:id="@+id/secondary_action_button"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingLeft="8dip"
- android:paddingRight="14dip"
- android:paddingStart="8dip"
- android:paddingEnd="14dip"
- android:background="?android:attr/selectableItemBackground"
- android:duplicateParentState="false"
- android:nextFocusLeft="@id/actions_view_container"/>
- <View
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:background="?android:attr/dividerVertical" />
-</merge>
diff --git a/res/layout/quickcontact_track.xml b/res/layout/quickcontact_track.xml
deleted file mode 100644
index 83a771c..0000000
--- a/res/layout/quickcontact_track.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<merge
- xmlns:android="http://schemas.android.com/apk/res/android">
- <HorizontalScrollView
- android:id="@+id/track_scroller"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:fadingEdgeLength="0dip"
- android:background="@color/quickcontact_track_background"
- android:scrollbars="none">
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <LinearLayout
- android:id="@+id/track"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal" />
- <View
- android:id="@+id/selected_tab_rectangle"
- android:layout_width="60dip"
- android:layout_height="6dip"
- android:layout_alignBottom="@id/track"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:background="@color/quickcontact_tab_indicator" />
- </RelativeLayout>
- </HorizontalScrollView>
-</merge>
diff --git a/res/layout/quickcontact_track_button.xml b/res/layout/quickcontact_track_button.xml
deleted file mode 100644
index f9dcd1d..0000000
--- a/res/layout/quickcontact_track_button.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<com.android.contacts.quickcontact.CheckableImageView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="60dip"
- android:layout_height="60dip"
- android:paddingLeft="12dip"
- android:paddingRight="12dip"
- android:paddingStart="12dip"
- android:paddingEnd="12dip"
- android:paddingTop="8dip"
- android:paddingBottom="8dip"
- android:scaleType="centerInside"
- android:focusable="true"
- android:clickable="true"
- android:background="?android:attr/selectableItemBackground" />
diff --git a/res/values/colors.xml b/res/values/colors.xml
index d1ea3b0..e53dc41 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -15,10 +15,6 @@
-->
<resources>
- <color name="quickcontact_list_divider">#ffcdcdcd</color>
- <color name="quickcontact_list_background">#ffe2e2e2</color>
- <color name="quickcontact_tab_indicator">#ffc6c6c6</color>
- <color name="quickcontact_track_background">#fff5f5f5</color>
<color name="quickcontact_activity_background">#fff5f5f5</color>
<color name="quickcontact_name_detail_background">#66000000</color>
@@ -43,4 +39,10 @@
<color name="tab_selected_color">#ffeeff41</color>
<color name="contacts_accent_color">#00acc1</color>
+ <!-- Color of the separator between entries in an ExpandingEntryCardView -->
+ <color name="expanding_entry_card_item_separator_color">#eeeeee</color>
+
+ <!-- Color of the text on an ExpandingEntryCard button -->
+ <color name="expanding_entry_card_button_text_color">@android:color/black</color>
+
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 40b4665..4995f71 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -133,4 +133,30 @@
wide screen devices). -->
<dimen name="contact_picker_contact_list_min_height">550dip</dimen>
+
+ <!-- Size of the title text for a ExpandingEntryCardView -->
+ <dimen name="expanding_entry_card_title_text_size">16sp</dimen>
+ <!-- Padding for the title text for a ExpandingEntryCardView -->
+ <dimen name="expanding_entry_card_title_padding">16dp</dimen>
+
+ <!-- Height of the separator between entries in an ExpandingEntryCardView -->
+ <dimen name="expanding_entry_card_item_separator_height">1dp</dimen>
+ <!-- Dimensions for an entry in ExpandingEntryCardView -->
+ <dimen name="expanding_entry_card_item_padding_start">67dp</dimen>
+ <dimen name="expanding_entry_card_item_padding_with_image_start">20dp</dimen>
+ <dimen name="expanding_entry_card_item_padding_end">20dp</dimen>
+ <dimen name="expanding_entry_card_item_padding_top">16dp</dimen>
+ <dimen name="expanding_entry_card_item_padding_bottom">16dp</dimen>
+ <dimen name="expanding_entry_card_item_image_spacing">16dp</dimen>
+
+ <!-- Dimensions for a button in ExpandingEntryCardView -->
+ <dimen name="expanding_entry_card_button_padding_start">20dp</dimen>
+ <dimen name="expanding_entry_card_button_padding_vertical">16dp</dimen>
+ <dimen name="expanding_entry_card_button_drawable_padding">20dp</dimen>
+
+ <dimen name="expanding_entry_card_item_text_icon_margin_top">7dp</dimen>
+ <dimen name="expanding_entry_card_item_text_icon_margin_right">7dp</dimen>
+ <dimen name="expanding_entry_card_item_sub_header_icon_margin_right">4dp</dimen>
+ <dimen name="expanding_entry_card_item_sub_header_icon_margin_bottom">14dp</dimen>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f40dbb0..6c368f5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -648,4 +648,12 @@
<!-- Content description for the button that adds a new contact
[CHAR LIMIT=NONE] -->
<string name="action_menu_add_new_contact_button">add new contact</string>
+ <!-- Button Label to see more on an ExpandingEntryCardView [CHAR LIMIT=40] -->
+ <string name="expanding_entry_card_view_see_more">See more</string>
+ <!-- Button Label to see less on an ExpandingEntryCardView [CHAR LIMIT=40] -->
+ <string name="expanding_entry_card_view_see_less">See less</string>
+
+ <!-- Title of communication card. [CHAR LIMIT=60] -->
+ <string name="communication_card_title">Contact</string>
+
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index dcce5ab..5ec06a8 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -41,7 +41,7 @@
<style name="Theme">
</style>
- <style name="Theme.QuickContact" parent="@android:style/Theme.Holo.Light">
+ <style name="Theme.QuickContact" parent="@android:style/Theme.Quantum.Light">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowFrame">@null</item>
@@ -223,12 +223,7 @@
<item name="android:layout_height">150dip</item>
</style>
- <style name="QuickContactListItemStyle">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:minHeight">?android:attr/listPreferredItemHeight</item>
- <item name="android:orientation">horizontal</item>
- <item name="android:gravity">center_vertical</item>
+ <style name="SelectableItem" parent="@android:style/Theme.Quantum.Light">
<item name="android:background">?android:attr/selectableItemBackground</item>
</style>
@@ -244,12 +239,6 @@
<item name="android:orientation">vertical</item>
</style>
- <style name="QuickContactListBottomStyle">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">2dip</item>
- <item name="android:background">@color/quickcontact_tab_indicator</item>
- </style>
-
<style name="Theme.PhotoSelector" parent="@android:style/Theme.Holo.Light">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
diff --git a/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java b/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
new file mode 100644
index 0000000..dc78d5b
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2014 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.quickcontact;
+
+import com.android.contacts.R;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.QuickContact;
+import android.support.v4.text.TextUtilsCompat;
+import android.support.v4.view.ViewCompat;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Display entries in a LinearLayout that can be expanded to show all entries.
+ */
+public class ExpandingEntryCardView extends LinearLayout {
+
+ private static final String TAG = "ExpandingEntryCardView";
+
+ /**
+ * Entry data.
+ */
+ public static final class Entry {
+
+ private final Drawable mIcon;
+ private final String mHeader;
+ private final String mSubHeader;
+ private final Drawable mSubHeaderIcon;
+ private final String mText;
+ private final Drawable mTextIcon;
+ private final Intent mIntent;
+ private final boolean mIsEditable;
+
+ public Entry(Drawable icon, String header, String subHeader, String text,
+ Intent intent, boolean isEditable) {
+ this(icon, header, subHeader, null, text, null, intent, isEditable);
+ }
+
+ public Entry(Drawable mainIcon, String header, String subHeader,
+ Drawable subHeaderIcon, String text, Drawable textIcon, Intent intent,
+ boolean isEditable) {
+ mIcon = mainIcon;
+ mHeader = header;
+ mSubHeader = subHeader;
+ mSubHeaderIcon = subHeaderIcon;
+ mText = text;
+ mTextIcon = textIcon;
+ mIntent = intent;
+ mIsEditable = isEditable;
+ }
+
+ Drawable getIcon() {
+ return mIcon;
+ }
+
+ String getHeader() {
+ return mHeader;
+ }
+
+ String getSubHeader() {
+ return mSubHeader;
+ }
+
+ Drawable getSubHeaderIcon() {
+ return mSubHeaderIcon;
+ }
+
+ public String getText() {
+ return mText;
+ }
+
+ Drawable getTextIcon() {
+ return mTextIcon;
+ }
+
+ Intent getIntent() {
+ return mIntent;
+ }
+
+ boolean isEditable() {
+ return mIsEditable;
+ }
+ }
+
+ private View mExpandCollapseButton;
+ private TextView mExpandCollapseTextView;
+ private TextView mTitleTextView;
+ private CharSequence mExpandButtonText;
+ private CharSequence mCollapseButtonText;
+ private OnClickListener mOnClickListener;
+ private boolean mIsExpanded = false;
+ private int mCollapsedEntriesCount;
+ private List<View> mEntryViews;
+ private LinearLayout mEntriesViewGroup;
+ private int mThemeColor;
+
+ private final OnClickListener mExpandCollapseButtonListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mIsExpanded) {
+ collapse();
+ } else {
+ expand();
+ }
+ }
+ };
+
+ public ExpandingEntryCardView(Context context) {
+ super(context);
+ LayoutInflater inflater = LayoutInflater.from(context);
+ View expandingEntryCardView = inflater.inflate(R.layout.expanding_entry_card_view, this);
+ mEntriesViewGroup = (LinearLayout)
+ expandingEntryCardView.findViewById(R.id.content_area_linear_layout);
+ mTitleTextView = (TextView) expandingEntryCardView.findViewById(R.id.title);
+ }
+
+ public ExpandingEntryCardView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ LayoutInflater inflater = LayoutInflater.from(context);
+ View expandingEntryCardView = inflater.inflate(R.layout.expanding_entry_card_view, this);
+ mEntriesViewGroup = (LinearLayout)
+ expandingEntryCardView.findViewById(R.id.content_area_linear_layout);
+ mTitleTextView = (TextView) expandingEntryCardView.findViewById(R.id.title);
+ }
+
+ /**
+ * Sets the Entry list to display.
+ *
+ * @param entries The Entry list to display.
+ */
+ public void initialize(List<Entry> entries, int numInitialVisibleEntries,
+ boolean isExpanded, int themeColor) {
+ LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+ mIsExpanded = isExpanded;
+ mEntryViews = createEntryViews(layoutInflater, entries);
+ mThemeColor = themeColor;
+ mCollapsedEntriesCount = Math.min(numInitialVisibleEntries, entries.size());
+ if (mExpandCollapseButton == null) {
+ createExpandButton(layoutInflater);
+ }
+ insertEntriesIntoViewGroup();
+ }
+
+ /**
+ * Sets the text for the expand button.
+ *
+ * @param expandButtonText The expand button text.
+ */
+ public void setExpandButtonText(CharSequence expandButtonText) {
+ mExpandButtonText = expandButtonText;
+ if (mExpandCollapseTextView != null && !mIsExpanded) {
+ mExpandCollapseTextView.setText(expandButtonText);
+ }
+ }
+
+ /**
+ * Sets the text for the expand button.
+ *
+ * @param expandButtonText The expand button text.
+ */
+ public void setCollapseButtonText(CharSequence expandButtonText) {
+ mCollapseButtonText = expandButtonText;
+ if (mExpandCollapseTextView != null && mIsExpanded) {
+ mExpandCollapseTextView.setText(mCollapseButtonText);
+ }
+ }
+
+ @Override
+ public void setOnClickListener(OnClickListener listener) {
+ mOnClickListener = listener;
+ }
+
+ private void insertEntriesIntoViewGroup() {
+ mEntriesViewGroup.removeAllViews();
+ for (int i = 0; i < mCollapsedEntriesCount; ++i) {
+ addEntry(mEntryViews.get(i));
+ }
+ if (mIsExpanded) {
+ for (int i = mCollapsedEntriesCount; i < mEntryViews.size(); ++i) {
+ addEntry(mEntryViews.get(i));
+ }
+ }
+
+ removeView(mExpandCollapseButton);
+ if (mCollapsedEntriesCount < mEntryViews.size()
+ && mExpandCollapseButton.getParent() == null) {
+ addView(mExpandCollapseButton, -1);
+ }
+ }
+
+ private void addEntry(View entry) {
+ if (mEntriesViewGroup.getChildCount() > 0) {
+ View separator = new View(getContext());
+ separator.setBackgroundColor(getResources().getColor(
+ R.color.expanding_entry_card_item_separator_color));
+ LayoutParams layoutParams = generateDefaultLayoutParams();
+ Resources resources = getResources();
+ layoutParams.height = resources.getDimensionPixelSize(
+ R.dimen.expanding_entry_card_item_separator_height);
+ if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ layoutParams.rightMargin = resources.getDimensionPixelSize(
+ R.dimen.expanding_entry_card_item_padding_start);
+ layoutParams.leftMargin = resources.getDimensionPixelSize(
+ R.dimen.expanding_entry_card_item_padding_end);
+ } else {
+ layoutParams.leftMargin = resources.getDimensionPixelSize(
+ R.dimen.expanding_entry_card_item_padding_start);
+ layoutParams.rightMargin = resources.getDimensionPixelSize(
+ R.dimen.expanding_entry_card_item_padding_end);
+ }
+ separator.setLayoutParams(layoutParams);
+ mEntriesViewGroup.addView(separator);
+ }
+ mEntriesViewGroup.addView(entry);
+ }
+
+ private CharSequence getExpandButtonText() {
+ if (!TextUtils.isEmpty(mExpandButtonText)) {
+ return mExpandButtonText;
+ } else {
+ // Default to "See more".
+ return getResources().getText(R.string.expanding_entry_card_view_see_more);
+ }
+ }
+
+ private CharSequence getCollapseButtonText() {
+ if (!TextUtils.isEmpty(mCollapseButtonText)) {
+ return mCollapseButtonText;
+ } else {
+ // Default to "See less".
+ return getResources().getText(R.string.expanding_entry_card_view_see_less);
+ }
+ }
+
+ private void createExpandButton(LayoutInflater layoutInflater) {
+ mExpandCollapseButton = layoutInflater.inflate(
+ R.layout.quickcontact_expanding_entry_card_button, this, false);
+ mExpandCollapseTextView = (TextView) mExpandCollapseButton.findViewById(R.id.text);
+ if (mIsExpanded) {
+ updateExpandCollapseButton(getCollapseButtonText());
+ } else {
+ updateExpandCollapseButton(getExpandButtonText());
+ }
+ mExpandCollapseButton.setOnClickListener(mExpandCollapseButtonListener);
+ }
+
+ private List<View> createEntryViews(LayoutInflater layoutInflater, List<Entry> entries) {
+ ArrayList<View> views = new ArrayList<View>(entries.size());
+ for (int i = 0; i < entries.size(); ++i) {
+ Entry entry = entries.get(i);
+ views.add(createEntryView(layoutInflater, entry));
+ }
+ return views;
+ }
+
+ private View createEntryView(LayoutInflater layoutInflater, Entry entry) {
+ View view = layoutInflater.inflate(
+ R.layout.expanding_entry_card_item, this, false);
+
+ ImageView icon = (ImageView) view.findViewById(R.id.icon);
+ icon.setImageDrawable(entry.getIcon());
+
+ TextView header = (TextView) view.findViewById(R.id.header);
+ if (entry.getHeader() != null) {
+ header.setText(entry.getHeader());
+ } else {
+ header.setVisibility(View.GONE);
+ }
+
+ TextView subHeader = (TextView) view.findViewById(R.id.sub_header);
+ if (entry.getSubHeader() != null) {
+ subHeader.setText(entry.getSubHeader());
+ } else {
+ subHeader.setVisibility(View.GONE);
+ }
+
+ ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header);
+ if (entry.getSubHeaderIcon() != null) {
+ subHeaderIcon.setImageDrawable(entry.getSubHeaderIcon());
+ } else {
+ subHeaderIcon.setVisibility(View.GONE);
+ }
+
+ TextView text = (TextView) view.findViewById(R.id.text);
+ if (entry.getText() != null) {
+ text.setText(entry.getText());
+ } else {
+ text.setVisibility(View.GONE);
+ }
+
+ ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text);
+ if (entry.getTextIcon() != null) {
+ textIcon.setImageDrawable(entry.getTextIcon());
+ } else {
+ textIcon.setVisibility(View.GONE);
+ }
+
+ if (entry.getIntent() != null) {
+ View entryLayout = view.findViewById(R.id.entry_layout);
+ entryLayout.setOnClickListener(mOnClickListener);
+ entryLayout.setTag(entry.getIntent());
+ }
+
+ return view;
+ }
+
+ private void updateExpandCollapseButton(CharSequence buttonText) {
+ int resId = mIsExpanded ? R.drawable.expanding_entry_card_collapse_white_24
+ : R.drawable.expanding_entry_card_expand_white_24;
+ // TODO: apply color theme to the drawable
+ Drawable drawable = getResources().getDrawable(resId);
+ if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ mExpandCollapseTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable,
+ null);
+ } else {
+ mExpandCollapseTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null,
+ null);
+ }
+ mExpandCollapseTextView.setText(buttonText);
+ }
+
+ private void expand() {
+ final int startingHeight = mEntriesViewGroup.getHeight();
+
+ mIsExpanded = true;
+ insertEntriesIntoViewGroup();
+ updateExpandCollapseButton(getCollapseButtonText());
+
+ createExpandAnimator(startingHeight, measureContentAreaHeight()).start();
+ }
+
+ private void collapse() {
+ int startingHeight = mEntriesViewGroup.getHeight();
+
+ // Figure out the height the view will be after the animation is finished.
+ mIsExpanded = false;
+ insertEntriesIntoViewGroup();
+ int finishHeight = measureContentAreaHeight();
+
+ // During the animation, mEntriesViewGroup should contain the same views as it did before
+ // the animation. Otherwise, the animation will look very silly.
+ mIsExpanded = true;
+ insertEntriesIntoViewGroup();
+
+ mIsExpanded = false;
+ updateExpandCollapseButton(getExpandButtonText());
+ createExpandAnimator(startingHeight, finishHeight).start();
+ }
+
+ private int measureContentAreaHeight() {
+ // Measure the LinearLayout, assuming no constraints from the parent.
+ final int widthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ final int heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ mEntriesViewGroup.measure(widthSpec, heightSpec);
+ return mEntriesViewGroup.getMeasuredHeight();
+ }
+
+ /**
+ * Create ValueAnimator that performs an expand animation on the content LinearLayout.
+ *
+ * The animation needs to be performed manually using a ValueAnimator, since LinearLayout
+ * doesn't have a single set-able height property (ie, no setHeight()).
+ */
+ private ValueAnimator createExpandAnimator(int start, int end) {
+ ValueAnimator animator = ValueAnimator.ofInt(start, end);
+ animator.setInterpolator(new AccelerateDecelerateInterpolator());
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ int value = (Integer) valueAnimator.getAnimatedValue();
+ ViewGroup.LayoutParams layoutParams = mEntriesViewGroup.getLayoutParams();
+ layoutParams.height = value;
+ mEntriesViewGroup.setLayoutParams(layoutParams);
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ insertEntriesIntoViewGroup();
+ }
+ });
+ return animator;
+ }
+
+ /**
+ * Returns whether the view is currently in its expanded state.
+ */
+ public boolean isExpanded() {
+ return mIsExpanded;
+ }
+
+ /**
+ * Sets the title text of this ExpandingEntryCardView.
+ * @param title The title to set. A null title will result in an empty string being set.
+ */
+ public void setTitle(String title) {
+ if (mTitleTextView == null) {
+ Log.e(TAG, "mTitleTextView is null");
+ }
+ if (title == null) {
+ mTitleTextView.setText("");
+ }
+ mTitleTextView.setText(title);
+ }
+}
diff --git a/src/com/android/contacts/quickcontact/FloatingChildLayout.java b/src/com/android/contacts/quickcontact/FloatingChildLayout.java
deleted file mode 100644
index 555f948..0000000
--- a/src/com/android/contacts/quickcontact/FloatingChildLayout.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * 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.quickcontact;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.animation.AnimationUtils;
-import android.widget.FrameLayout;
-import android.widget.PopupWindow;
-
-import com.android.contacts.R;
-import com.android.contacts.test.NeededForReflection;
-import com.android.contacts.util.SchedulingUtils;
-
-/**
- * Layout containing single child {@link View} which it attempts to center
- * around {@link #setChildTargetScreen(Rect)}.
- * <p>
- * Updates drawable state to be {@link android.R.attr#state_first} when child is
- * above target, and {@link android.R.attr#state_last} when child is below
- * target. Also updates {@link Drawable#setLevel(int)} on child
- * {@link View#getBackground()} to reflect horizontal center of target.
- * <p>
- * The reason for this approach is because target {@link Rect} is in screen
- * coordinates disregarding decor insets; otherwise something like
- * {@link PopupWindow} might work better.
- */
-public class FloatingChildLayout extends FrameLayout {
- private static final String TAG = "FloatingChildLayout";
- private int mFixedTopPosition;
- private View mChild;
- private Rect mTargetScreen = new Rect();
- private final int mAnimationDuration;
-
- /** The phase of the background dim. This is one of the values of {@link BackgroundPhase} */
- private int mBackgroundPhase = BackgroundPhase.BEFORE;
-
- private ObjectAnimator mBackgroundAnimator = ObjectAnimator.ofInt(this,
- "backgroundColorAlpha", 0, DIM_BACKGROUND_ALPHA);
-
- private interface BackgroundPhase {
- public static final int BEFORE = 0;
- public static final int APPEARING_OR_VISIBLE = 1;
- public static final int DISAPPEARING_OR_GONE = 3;
- }
-
- /** The phase of the contents window. This is one of the values of {@link ForegroundPhase} */
- private int mForegroundPhase = ForegroundPhase.BEFORE;
-
- private interface ForegroundPhase {
- public static final int BEFORE = 0;
- public static final int APPEARING = 1;
- public static final int IDLE = 2;
- public static final int DISAPPEARING = 3;
- public static final int AFTER = 4;
- }
-
- // Black, 50% alpha as per the system default.
- private static final int DIM_BACKGROUND_ALPHA = 0x7F;
-
- public FloatingChildLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- final Resources resources = getResources();
- mFixedTopPosition =
- resources.getDimensionPixelOffset(R.dimen.quick_contact_top_position);
- mAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime);
-
- super.setBackground(new ColorDrawable(0));
- }
-
- @Override
- protected void onFinishInflate() {
- mChild = findViewById(android.R.id.content);
- mChild.setDuplicateParentStateEnabled(true);
-
- // this will be expanded in showChild()
- mChild.setScaleX(0.5f);
- mChild.setScaleY(0.5f);
- mChild.setAlpha(0.0f);
- }
-
- public View getChild() {
- return mChild;
- }
-
- /**
- * FloatingChildLayout manages its own background, don't set it.
- */
- @Override
- public void setBackground(Drawable background) {
- Log.wtf(TAG, "don't setBackground(), it is managed internally");
- }
-
- /**
- * Set {@link Rect} in screen coordinates that {@link #getChild()} should be
- * centered around.
- */
- public void setChildTargetScreen(Rect targetScreen) {
- mTargetScreen = targetScreen;
- requestLayout();
- }
-
- /**
- * Return {@link #mTargetScreen} in local window coordinates, taking any
- * decor insets into account.
- */
- private Rect getTargetInWindow() {
- final Rect windowScreen = new Rect();
- getWindowVisibleDisplayFrame(windowScreen);
-
- final Rect target = new Rect(mTargetScreen);
- target.offset(-windowScreen.left, -windowScreen.top);
- return target;
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-
- final View child = mChild;
- final Rect target = getTargetInWindow();
-
- final int childWidth = child.getMeasuredWidth();
- final int childHeight = child.getMeasuredHeight();
-
- if (mFixedTopPosition != -1) {
- // Horizontally centered, vertically fixed position
- final int childLeft = (getWidth() - childWidth) / 2;
- final int childTop = mFixedTopPosition;
- layoutChild(child, childLeft, childTop);
- } else {
- // default is centered horizontally around target...
- final int childLeft = target.centerX() - (childWidth / 2);
- // ... and vertically aligned a bit below centered
- final int childTop = target.centerY() - Math.round(childHeight * 0.35f);
-
- // when child is outside bounds, nudge back inside
- final int clampedChildLeft = clampDimension(childLeft, childWidth, getWidth());
- final int clampedChildTop = clampDimension(childTop, childHeight, getHeight());
-
- layoutChild(child, clampedChildLeft, clampedChildTop);
- }
- }
-
- private static int clampDimension(int value, int size, int max) {
- // when larger than bounds, just center
- if (size > max) {
- return (max - size) / 2;
- }
-
- // clamp to bounds
- return Math.min(Math.max(value, 0), max - size);
- }
-
- private static void layoutChild(View child, int left, int top) {
- child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
- }
-
- @NeededForReflection
- public void setBackgroundColorAlpha(int alpha) {
- setBackgroundColor(alpha << 24);
- }
-
- public void fadeInBackground() {
- if (mBackgroundPhase == BackgroundPhase.BEFORE) {
- mBackgroundPhase = BackgroundPhase.APPEARING_OR_VISIBLE;
-
- createChildLayer();
-
- SchedulingUtils.doAfterDraw(this, new Runnable() {
- @Override
- public void run() {
- mBackgroundAnimator.setDuration(mAnimationDuration).start();
- }
- });
- }
- }
-
- public void fadeOutBackground() {
- if (mBackgroundPhase == BackgroundPhase.APPEARING_OR_VISIBLE) {
- mBackgroundPhase = BackgroundPhase.DISAPPEARING_OR_GONE;
- if (mBackgroundAnimator.isRunning()) {
- mBackgroundAnimator.reverse();
- } else {
- ObjectAnimator.ofInt(this, "backgroundColorAlpha", DIM_BACKGROUND_ALPHA, 0).
- setDuration(mAnimationDuration).start();
- }
- }
- }
-
- public boolean isContentFullyVisible() {
- return mForegroundPhase == ForegroundPhase.IDLE;
- }
-
- /** Begin animating {@link #getChild()} visible. */
- public void showContent(final Runnable onAnimationEndRunnable) {
- if (mForegroundPhase == ForegroundPhase.BEFORE) {
- mForegroundPhase = ForegroundPhase.APPEARING;
- animateScale(false, onAnimationEndRunnable);
- }
- }
-
- /**
- * Begin animating {@link #getChild()} invisible. Returns false if animation is not valid in
- * this state
- */
- public boolean hideContent(final Runnable onAnimationEndRunnable) {
- if (mForegroundPhase == ForegroundPhase.APPEARING ||
- mForegroundPhase == ForegroundPhase.IDLE) {
- mForegroundPhase = ForegroundPhase.DISAPPEARING;
-
- createChildLayer();
-
- animateScale(true, onAnimationEndRunnable);
- return true;
- } else {
- return false;
- }
- }
-
- private void createChildLayer() {
- mChild.invalidate();
- mChild.setLayerType(LAYER_TYPE_HARDWARE, null);
- mChild.buildLayer();
- }
-
- /** Creates the open/close animation */
- private void animateScale(
- final boolean isExitAnimation,
- final Runnable onAnimationEndRunnable) {
- mChild.setPivotX(mTargetScreen.centerX() - mChild.getLeft());
- mChild.setPivotY(mTargetScreen.centerY() - mChild.getTop());
-
- final int scaleInterpolator = isExitAnimation
- ? android.R.interpolator.accelerate_quint
- : android.R.interpolator.decelerate_quint;
- final float scaleTarget = isExitAnimation ? 0.5f : 1.0f;
-
- mChild.animate()
- .setDuration(mAnimationDuration)
- .setInterpolator(AnimationUtils.loadInterpolator(getContext(), scaleInterpolator))
- .scaleX(scaleTarget)
- .scaleY(scaleTarget)
- .alpha(isExitAnimation ? 0.0f : 1.0f)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mChild.setLayerType(LAYER_TYPE_NONE, null);
- if (isExitAnimation) {
- if (mForegroundPhase == ForegroundPhase.DISAPPEARING) {
- mForegroundPhase = ForegroundPhase.AFTER;
- if (onAnimationEndRunnable != null) onAnimationEndRunnable.run();
- }
- } else {
- if (mForegroundPhase == ForegroundPhase.APPEARING) {
- mForegroundPhase = ForegroundPhase.IDLE;
- if (onAnimationEndRunnable != null) onAnimationEndRunnable.run();
- }
- }
- }
- });
- }
-
- private View.OnTouchListener mOutsideTouchListener;
-
- public void setOnOutsideTouchListener(View.OnTouchListener listener) {
- mOutsideTouchListener = listener;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- // at this point, touch wasn't handled by child view; assume outside
- if (mOutsideTouchListener != null) {
- return mOutsideTouchListener.onTouch(this, event);
- }
- return false;
- }
-}
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index db3a341..861cb66 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -55,6 +55,7 @@
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -74,12 +75,15 @@
import com.android.contacts.common.util.Constants;
import com.android.contacts.common.util.DataStatus;
import com.android.contacts.common.util.UriUtils;
+import com.android.contacts.quickcontact.ExpandingEntryCardView.Entry;
import com.android.contacts.util.ImageViewDrawableSetter;
import com.android.contacts.util.SchedulingUtils;
import com.android.contacts.common.util.StopWatch;
+
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -108,19 +112,12 @@
private String[] mExcludeMimes;
private List<String> mSortedActionMimeTypes = Lists.newArrayList();
- private FloatingChildLayout mFloatingLayout;
-
private View mPhotoContainer;
- private ViewGroup mTrack;
- private HorizontalScrollView mTrackScroller;
- private View mSelectedTabRectangle;
- private View mLineAfterTrack;
private ImageView mPhotoView;
private ImageView mOpenDetailsOrAddContactImage;
private ImageView mStarImage;
- private ViewPager mListPager;
- private ViewPagerAdapter mPagerAdapter;
+ private ExpandingEntryCardView mCommunicationCard;
private Contact mContactData;
private ContactLoader mContactLoader;
@@ -170,7 +167,6 @@
mContactLoader.cacheResult();
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(intent);
- close(false);
}
};
@@ -194,6 +190,18 @@
}
};
+ final OnClickListener mEntryClickHandler = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Log.i(TAG, "mEntryClickHandler onClick");
+ Object intent = v.getTag();
+ if (intent == null || !(intent instanceof Intent)) {
+ return;
+ }
+ startActivity((Intent) intent);
+ }
+ };
+
@Override
protected void onCreate(Bundle icicle) {
mStopWatch.lap("c"); // create start
@@ -234,33 +242,13 @@
mStopWatch.lap("l"); // layout inflated
- mFloatingLayout = (FloatingChildLayout) findViewById(R.id.floating_layout);
- mTrack = (ViewGroup) findViewById(R.id.track);
- mTrackScroller = (HorizontalScrollView) findViewById(R.id.track_scroller);
mOpenDetailsOrAddContactImage = (ImageView) findViewById(R.id.contact_details_image);
mStarImage = (ImageView) findViewById(R.id.quickcontact_star_button);
- mListPager = (ViewPager) findViewById(R.id.item_list_pager);
- mSelectedTabRectangle = findViewById(R.id.selected_tab_rectangle);
- mLineAfterTrack = findViewById(R.id.line_after_track);
-
- mFloatingLayout.setOnOutsideTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- handleOutsideTouch();
- return true;
- }
- });
+ mCommunicationCard = (ExpandingEntryCardView) findViewById(R.id.communication_card);
+ mCommunicationCard.setTitle(getResources().getString(R.string.communication_card_title));
mOpenDetailsOrAddContactImage.setOnClickListener(mOpenDetailsClickHandler);
-
- mPagerAdapter = new ViewPagerAdapter(getFragmentManager());
- mListPager.setAdapter(mPagerAdapter);
- mListPager.setOnPageChangeListener(new PageChangeListener());
-
- final Rect sourceBounds = intent.getSourceBounds();
- if (sourceBounds != null) {
- mFloatingLayout.setChildTargetScreen(sourceBounds);
- }
+ mCommunicationCard.setOnClickListener(mEntryClickHandler);
// find and prepare correct header view
mPhotoContainer = findViewById(R.id.photo_container);
@@ -272,68 +260,17 @@
mStopWatch.lap("v"); // view initialized
- SchedulingUtils.doAfterLayout(mFloatingLayout, new Runnable() {
+ // TODO: Use some sort of fading in for the layout and content during animation
+ /*SchedulingUtils.doAfterLayout(mFloatingLayout, new Runnable() {
@Override
public void run() {
mFloatingLayout.fadeInBackground();
}
- });
+ });*/
mStopWatch.lap("cf"); // onCreate finished
}
- private void handleOutsideTouch() {
- if (mFloatingLayout.isContentFullyVisible()) {
- close(true);
- }
- }
-
- private void close(boolean withAnimation) {
- // cancel any pending queries
- getLoaderManager().destroyLoader(LOADER_ID);
-
- if (withAnimation) {
- mFloatingLayout.fadeOutBackground();
- final boolean animated = mFloatingLayout.hideContent(new Runnable() {
- @Override
- public void run() {
- // Wait until the final animation frame has been drawn, otherwise
- // there is jank as the framework transitions to the next Activity.
- SchedulingUtils.doAfterDraw(mFloatingLayout, new Runnable() {
- @Override
- public void run() {
- // Unfortunately, we need to also use postDelayed() to wait a moment
- // for the frame to be drawn, else the framework's activity-transition
- // animation will kick in before the final frame is available to it.
- // This seems unavoidable. The problem isn't merely that there is no
- // post-draw listener API; if that were so, it would be sufficient to
- // call post() instead of postDelayed().
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- finish();
- overridePendingTransition(0, 0);
- }
- }, POST_DRAW_WAIT_DURATION);
- }
- });
- }
- });
- if (!animated) {
- // If we were in the wrong state, simply quit (this can happen for example
- // if the user pushes BACK before anything has loaded)
- finish();
- }
- } else {
- finish();
- }
- }
-
- @Override
- public void onBackPressed() {
- close(true);
- }
-
/** Assign this string to the view if it is not empty. */
private void setHeaderNameText(int id, int resId) {
setHeaderNameText(id, getText(resId));
@@ -483,6 +420,8 @@
setHeaderNameText(R.id.name, data.getDisplayName());
+ // List of Entry that makes up the ExpandingEntryCardView
+ final List<Entry> entries = new ArrayList<>();
// All the mime-types to add.
final Set<String> containedTypes = new HashSet<String>(mActions.keySet());
mSortedActionMimeTypes.clear();
@@ -491,6 +430,7 @@
if (containedTypes.contains(mimeType)) {
mSortedActionMimeTypes.add(mimeType);
containedTypes.remove(mimeType);
+ entries.addAll(actionsToEntries(mActions.get(mimeType)));
}
}
@@ -499,6 +439,7 @@
if (!TRAILING_MIMETYPES.contains(mimeType)) {
mSortedActionMimeTypes.add(mimeType);
containedTypes.remove(mimeType);
+ entries.addAll(actionsToEntries(mActions.get(mimeType)));
}
}
@@ -507,26 +448,14 @@
if (containedTypes.contains(mimeType)) {
containedTypes.remove(mimeType);
mSortedActionMimeTypes.add(mimeType);
+ entries.addAll(actionsToEntries(mActions.get(mimeType)));
}
}
- mPagerAdapter.notifyDataSetChanged();
-
- mStopWatch.lap("mt"); // Mime types initialized
-
- // Add buttons for each mimetype
- mTrack.removeAllViews();
- for (String mimeType : mSortedActionMimeTypes) {
- final View actionView = inflateAction(mimeType, cache, mTrack, data.getDisplayName());
- mTrack.addView(actionView);
- }
-
- mStopWatch.lap("mt"); // Buttons added
+ mCommunicationCard.initialize(entries, /* numInitialVisibleEntries = */ 1,
+ /* isExpanded = */ false, /* themeColor = */ 0);
final boolean hasData = !mSortedActionMimeTypes.isEmpty();
- mTrackScroller.setVisibility(hasData ? View.VISIBLE : View.GONE);
- mSelectedTabRectangle.setVisibility(hasData ? View.VISIBLE : View.GONE);
- mLineAfterTrack.setVisibility(hasData ? View.VISIBLE : View.GONE);
- mListPager.setVisibility(hasData ? View.VISIBLE : View.GONE);
+ mCommunicationCard.setVisibility(hasData ? View.VISIBLE: View.GONE);
}
/**
@@ -565,37 +494,18 @@
}
/**
- * Inflate the in-track view for the action of the given MIME-type, collapsing duplicate values.
- * Will use the icon provided by the {@link DataKind}.
+ * Converts a list of Action into a list of Entry
+ * @param actions The list of Action to convert
+ * @return The converted list of Entry
*/
- private View inflateAction(String mimeType, ResolveCache resolveCache,
- ViewGroup root, String name) {
- final CheckableImageView typeView = (CheckableImageView) getLayoutInflater().inflate(
- R.layout.quickcontact_track_button, root, false);
-
- List<Action> children = mActions.get(mimeType);
- typeView.setTag(mimeType);
- final Action firstInfo = children.get(0);
-
- // Set icon and listen for clicks
- final CharSequence descrip = resolveCache.getDescription(firstInfo, name);
- final Drawable icon = resolveCache.getIcon(firstInfo);
- typeView.setChecked(false);
- typeView.setContentDescription(descrip);
- typeView.setImageDrawable(icon);
- typeView.setOnClickListener(mTypeViewClickListener);
-
- return typeView;
- }
-
- private CheckableImageView getActionViewAt(int position) {
- return (CheckableImageView) mTrack.getChildAt(position);
- }
-
- @Override
- public void onAttachFragment(Fragment fragment) {
- final QuickContactListFragment listFragment = (QuickContactListFragment) fragment;
- listFragment.setListener(mListFragmentListener);
+ private List<Entry> actionsToEntries(List<Action> actions) {
+ List<Entry> entries = new ArrayList<>();
+ for (Action action : actions) {
+ entries.add(new Entry(ResolveCache.getInstance(this).getIcon(action),
+ action.getMimeType(), action.getSubtitle().toString(),
+ action.getBody().toString(), action.getIntent(), /* isEditable= */ false));
+ }
+ return entries;
}
private LoaderCallbacks<Contact> mLoaderCallbacks =
@@ -608,7 +518,6 @@
public void onLoadFinished(Loader<Contact> loader, Contact data) {
mStopWatch.lap("lf"); // onLoadFinished
if (isFinishing()) {
- close(false);
return;
}
if (data.isError()) {
@@ -620,7 +529,6 @@
Log.i(TAG, "No contact found: " + ((ContactLoader)loader).getLookupUri());
Toast.makeText(QuickContactActivity.this, R.string.invalidContactMessage,
Toast.LENGTH_LONG).show();
- close(false);
return;
}
@@ -635,7 +543,8 @@
// Data bound and ready, pull curtain to show. Put this on the Handler to ensure
// that the layout passes are completed
- SchedulingUtils.doAfterLayout(mFloatingLayout, new Runnable() {
+ // TODO: Add animation here
+ /*SchedulingUtils.doAfterLayout(mFloatingLayout, new Runnable() {
@Override
public void run() {
mFloatingLayout.showContent(new Runnable() {
@@ -645,7 +554,7 @@
}
});
}
- });
+ });*/
mStopWatch.stopAndLog(TAG, 0);
mStopWatch = StopWatch.getNullStopWatch(); // We're done with it.
}
@@ -660,115 +569,4 @@
false /*postViewNotification*/, true /*computeFormattedPhoneNumber*/);
}
};
-
- /** A type (e.g. Call/Addresses was clicked) */
- private final OnClickListener mTypeViewClickListener = new OnClickListener() {
- @Override
- public void onClick(View view) {
- final CheckableImageView actionView = (CheckableImageView)view;
- final String mimeType = (String) actionView.getTag();
- int index = mSortedActionMimeTypes.indexOf(mimeType);
- mListPager.setCurrentItem(index, true);
- }
- };
-
- private class ViewPagerAdapter extends FragmentPagerAdapter {
- public ViewPagerAdapter(FragmentManager fragmentManager) {
- super(fragmentManager);
- }
-
- @Override
- public Fragment getItem(int position) {
- final String mimeType = mSortedActionMimeTypes.get(position);
- QuickContactListFragment fragment = new QuickContactListFragment(mimeType);
- final List<Action> actions = mActions.get(mimeType);
- fragment.setActions(actions);
- return fragment;
- }
-
- @Override
- public int getCount() {
- return mSortedActionMimeTypes.size();
- }
-
- @Override
- public int getItemPosition(Object object) {
- final QuickContactListFragment fragment = (QuickContactListFragment) object;
- final String mimeType = fragment.getMimeType();
- for (int i = 0; i < mSortedActionMimeTypes.size(); i++) {
- if (mimeType.equals(mSortedActionMimeTypes.get(i))) {
- return i;
- }
- }
- return PagerAdapter.POSITION_NONE;
- }
- }
-
- private class PageChangeListener extends SimpleOnPageChangeListener {
- private int mScrollingState = ViewPager.SCROLL_STATE_IDLE;
-
- @Override
- public void onPageSelected(int position) {
- final CheckableImageView actionView = getActionViewAt(position);
- if (actionView == null) {
- return;
- }
- mTrackScroller.requestChildRectangleOnScreen(actionView,
- new Rect(0, 0, actionView.getWidth(), actionView.getHeight()), false);
- // Don't render rectangle if we are currently scrolling to prevent it from flickering
- if (mScrollingState == ViewPager.SCROLL_STATE_IDLE) {
- renderSelectedRectangle(position, 0);
- }
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
- super.onPageScrollStateChanged(state);
- mScrollingState = state;
- }
-
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- renderSelectedRectangle(position, positionOffset);
- }
-
- private void renderSelectedRectangle(int position, float positionOffset) {
- final RelativeLayout.LayoutParams layoutParams =
- (RelativeLayout.LayoutParams) mSelectedTabRectangle.getLayoutParams();
- final int width = layoutParams.width;
- layoutParams.setMarginStart((int) ((position + positionOffset) * width));
- mSelectedTabRectangle.setLayoutParams(layoutParams);
- }
- }
-
- private final QuickContactListFragment.Listener mListFragmentListener =
- new QuickContactListFragment.Listener() {
- @Override
- public void onOutsideClick() {
- // If there is no background, we want to dismiss, because to the user it seems
- // like he had touched outside. If the ViewPager is solid however, those taps
- // must be ignored
- final boolean isTransparent = mListPager.getBackground() == null;
- if (isTransparent) handleOutsideTouch();
- }
-
- @Override
- public void onItemClicked(final Action action, final boolean alternate) {
- final Runnable startAppRunnable = new Runnable() {
- @Override
- public void run() {
- try {
- startActivity(alternate ? action.getAlternateIntent() : action.getIntent());
- } catch (ActivityNotFoundException e) {
- Toast.makeText(QuickContactActivity.this, R.string.quickcontact_missing_app,
- Toast.LENGTH_SHORT).show();
- }
-
- close(false);
- }
- };
- // Defer the action to make the window properly repaint
- new Handler().post(startAppRunnable);
- }
- };
}
diff --git a/src/com/android/contacts/quickcontact/QuickContactListFragment.java b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
deleted file mode 100644
index 761c854..0000000
--- a/src/com/android/contacts/quickcontact/QuickContactListFragment.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * 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.quickcontact;
-
-import android.app.Fragment;
-import android.content.ClipboardManager;
-import android.content.ClipData;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnLongClickListener;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.contacts.common.ContactPresenceIconUtil;
-import com.android.contacts.R;
-
-import java.util.List;
-
-/** A fragment that shows the list of resolve items below a tab */
-public class QuickContactListFragment extends Fragment {
- private ListView mListView;
- private List<Action> mActions;
- private RelativeLayout mFragmentContainer;
- private Listener mListener;
- private String mMimeType;
- private ClipboardManager mClipBoard;
- private Toast mLongPressToast;
-
- public QuickContactListFragment(String mimeType) {
- setRetainInstance(true);
- this.mMimeType = mimeType;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
- mFragmentContainer = (RelativeLayout) inflater.inflate(R.layout.quickcontact_list_fragment,
- container, false);
- mListView = (ListView) mFragmentContainer.findViewById(R.id.list);
- mListView.setItemsCanFocus(true);
-
- mFragmentContainer.setOnClickListener(mOutsideClickListener);
- mClipBoard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
- mLongPressToast = Toast.makeText(getActivity(),
- R.string.toast_text_copied, Toast.LENGTH_SHORT);
-
- configureAdapter();
- return mFragmentContainer;
- }
-
- public String getMimeType() {
- return mMimeType;
- }
-
- public void setActions(List<Action> actions) {
- mActions = actions;
- configureAdapter();
- }
-
- public void setListener(Listener value) {
- mListener = value;
- }
-
- private void configureAdapter() {
- if (mActions == null || mListView == null) return;
-
- mListView.setAdapter(new BaseAdapter() {
- @Override
- public int getCount() {
- return mActions.size();
- }
-
- @Override
- public Object getItem(int position) {
- return mActions.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // Set action title based on summary value
- final Action action = mActions.get(position);
- String mimeType = action.getMimeType();
-
- final View resultView = convertView != null ? convertView
- : getActivity().getLayoutInflater().inflate(
- mimeType.equals(StructuredPostal.CONTENT_ITEM_TYPE) ?
- R.layout.quickcontact_list_item_address :
- R.layout.quickcontact_list_item,
- parent, false);
-
- // TODO: Put those findViewByIds in a container
- final TextView text1 = (TextView) resultView.findViewById(
- android.R.id.text1);
- final TextView text2 = (TextView) resultView.findViewById(
- android.R.id.text2);
- final View actionsContainer = resultView.findViewById(
- R.id.actions_view_container);
- final ImageView alternateActionButton = (ImageView) resultView.findViewById(
- R.id.secondary_action_button);
- final View alternateActionDivider = resultView.findViewById(R.id.vertical_divider);
- final ImageView presenceIconView =
- (ImageView) resultView.findViewById(R.id.presence_icon);
-
- actionsContainer.setOnClickListener(mPrimaryActionClickListener);
- actionsContainer.setOnLongClickListener(mPrimaryActionLongClickListener);
- actionsContainer.setTag(action);
- alternateActionButton.setOnClickListener(mSecondaryActionClickListener);
- alternateActionButton.setTag(action);
-
- final boolean hasAlternateAction = action.getAlternateIntent() != null;
- alternateActionDivider.setVisibility(hasAlternateAction ? View.VISIBLE : View.GONE);
- alternateActionButton.setImageDrawable(action.getAlternateIcon());
- alternateActionButton.setContentDescription(action.getAlternateIconDescription());
- alternateActionButton.setVisibility(hasAlternateAction ? View.VISIBLE : View.GONE);
-
- if (mimeType.equals(Phone.CONTENT_ITEM_TYPE)) {
- // Force LTR text direction for phone numbers
- text1.setTextDirection(View.TEXT_DIRECTION_LTR);
-
- // Special case for phone numbers in accessibility mode
- text1.setContentDescription(getActivity().getString(
- R.string.description_dial_phone_number, action.getBody()));
- if (hasAlternateAction) {
- alternateActionButton.setContentDescription(getActivity()
- .getString(R.string.description_send_message, action.getBody()));
- }
- }
-
- text1.setText(action.getBody());
- if (text2 != null) {
- CharSequence subtitle = action.getSubtitle();
- text2.setText(subtitle);
- if (TextUtils.isEmpty(subtitle)) {
- text2.setVisibility(View.GONE);
- } else {
- text2.setVisibility(View.VISIBLE);
- }
- }
- final Drawable presenceIcon = ContactPresenceIconUtil.getPresenceIcon(
- getActivity(), action.getPresence());
- if (presenceIcon != null) {
- presenceIconView.setImageDrawable(presenceIcon);
- presenceIconView.setVisibility(View.VISIBLE);
- } else {
- presenceIconView.setVisibility(View.GONE);
- }
- 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 data item was long clicked */
- protected final OnLongClickListener mPrimaryActionLongClickListener = new OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- final Action action = (Action) v.getTag();
- ClipData clip = android.content.ClipData.newPlainText(
- action.getSubtitle(), action.getBody());
- mClipBoard.setPrimaryClip(clip);
- mLongPressToast.show();
- return true;
- }
- };
-
- /** A secondary action (SMS) was clicked */
- protected final OnClickListener mSecondaryActionClickListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- final Action action = (Action) v.getTag();
- if (mListener != null) mListener.onItemClicked(action, true);
- }
- };
-
- private final OnClickListener mOutsideClickListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mListener != null) mListener.onOutsideClick();
- }
- };
-
- public interface Listener {
- void onOutsideClick();
- void onItemClicked(Action action, boolean alternate);
- }
-}