12d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos/* 22d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Copyright (C) 2014 The Android Open Source Project 32d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 42d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Licensed under the Apache License, Version 2.0 (the "License"); 52d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * you may not use this file except in compliance with the License. 62d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * You may obtain a copy of the License at 72d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 82d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * http://www.apache.org/licenses/LICENSE-2.0 92d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Unless required by applicable law or agreed to in writing, software 112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * distributed under the License is distributed on an "AS IS" BASIS, 122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * See the License for the specific language governing permissions and 142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * limitations under the License. 152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulospackage com.android.contacts.quickcontact; 172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 18245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwellimport android.animation.Animator; 19245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwellimport android.animation.Animator.AnimatorListener; 20245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwellimport android.animation.AnimatorSet; 21c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulosimport android.animation.ObjectAnimator; 225f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunnimport android.app.Activity; 232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.Context; 242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.Intent; 252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.res.Resources; 267b0b0ce616c6c2fa149918c112128388712f5657Paul Soulosimport android.graphics.ColorFilter; 27dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulosimport android.graphics.Rect; 282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.graphics.drawable.Drawable; 295f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunnimport android.os.Bundle; 30ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulosimport android.support.v7.widget.CardView; 317ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jangimport android.text.Spannable; 322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.text.TextUtils; 330cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.ChangeBounds; 340cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Fade; 350cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Transition; 360cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Transition.TransitionListener; 370cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.TransitionManager; 380cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.TransitionSet; 392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.AttributeSet; 402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.Log; 41245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwellimport android.util.Property; 422a4207fb39330e840436215c896cde911489e111Paul Soulosimport android.view.ContextMenu.ContextMenuInfo; 432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.LayoutInflater; 4448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulosimport android.view.MotionEvent; 452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.View; 4648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulosimport android.view.ViewConfiguration; 472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.ViewGroup; 482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.ImageView; 492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.LinearLayout; 504b943553afdb7286b33e4bc2481431e816c57967Paul Soulosimport android.widget.RelativeLayout; 512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.TextView; 522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 530cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport com.android.contacts.R; 5469c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.dialog.CallSubjectDialog; 550cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.ArrayList; 572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.List; 582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos/** 602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Display entries in a LinearLayout that can be expanded to show all entries. 612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 62ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulospublic class ExpandingEntryCardView extends CardView { 632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private static final String TAG = "ExpandingEntryCardView"; 650cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private static final int DURATION_EXPAND_ANIMATION_FADE_IN = 200; 66245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell private static final int DURATION_COLLAPSE_ANIMATION_FADE_OUT = 75; 670cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private static final int DELAY_EXPAND_ANIMATION_FADE_IN = 100; 680cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 690cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public static final int DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS = 300; 700cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public static final int DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS = 300; 712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 72245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell private static final Property<View, Integer> VIEW_LAYOUT_HEIGHT_PROPERTY = 73245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell new Property<View, Integer>(Integer.class, "height") { 74245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell @Override 75245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell public void set(View view, Integer height) { 76245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) 77245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell view.getLayoutParams(); 78245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell params.height = height; 79245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell view.setLayoutParams(params); 80245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell } 81245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell 82245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell @Override 83245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell public Integer get(View view) { 84245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell return view.getLayoutParams().height; 85245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell } 86245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell }; 87245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell 882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Entry data. 902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public static final class Entry { 925f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn // No action when clicking a button is specified. 935f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn public static final int ACTION_NONE = 1; 945f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn // Button action is an intent. 955f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn public static final int ACTION_INTENT = 2; 965f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn // Button action will open the call with subject dialog. 975f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn public static final int ACTION_CALL_WITH_SUBJECT = 3; 982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 992ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos private final int mId; 1002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mIcon; 1012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mHeader; 1022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mSubHeader; 1032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mSubHeaderIcon; 1042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mText; 1052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mTextIcon; 1067ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang private Spannable mPrimaryContentDescription; 1072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Intent mIntent; 108dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final Drawable mAlternateIcon; 109dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final Intent mAlternateIntent; 1105da55ff837f57a63b409cd495cc25f61ed6fd709Wenyi Wang private Spannable mAlternateContentDescription; 11148ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos private final boolean mShouldApplyColor; 1122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final boolean mIsEditable; 1132a4207fb39330e840436215c896cde911489e111Paul Soulos private final EntryContextMenuInfo mEntryContextMenuInfo; 11448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final Drawable mThirdIcon; 11548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final Intent mThirdIntent; 11648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final String mThirdContentDescription; 11748290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos private final int mIconResourceId; 1185f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn private final int mThirdAction; 1195f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn private final Bundle mThirdExtras; 120d23de6146c23a27836a96e8a6f10a74346a905ddGary Mai private final boolean mShouldApplyThirdIconColor; 1212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1222ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public Entry(int id, Drawable mainIcon, String header, String subHeader, 12323e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos Drawable subHeaderIcon, String text, Drawable textIcon, 1247ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang Spannable primaryContentDescription, Intent intent, 1255da55ff837f57a63b409cd495cc25f61ed6fd709Wenyi Wang Drawable alternateIcon, Intent alternateIntent, 1265da55ff837f57a63b409cd495cc25f61ed6fd709Wenyi Wang Spannable alternateContentDescription, boolean shouldApplyColor, boolean isEditable, 12748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos EntryContextMenuInfo entryContextMenuInfo, Drawable thirdIcon, Intent thirdIntent, 1285f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn String thirdContentDescription, int thirdAction, Bundle thirdExtras, 129d23de6146c23a27836a96e8a6f10a74346a905ddGary Mai boolean shouldApplyThirdIconColor, int iconResourceId) { 1302ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mId = id; 1312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIcon = mainIcon; 1322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mHeader = header; 1332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mSubHeader = subHeader; 1342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mSubHeaderIcon = subHeaderIcon; 1352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mText = text; 1362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTextIcon = textIcon; 13723e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos mPrimaryContentDescription = primaryContentDescription; 1382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIntent = intent; 139dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateIcon = alternateIcon; 140dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateIntent = alternateIntent; 141dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateContentDescription = alternateContentDescription; 14248ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos mShouldApplyColor = shouldApplyColor; 1432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsEditable = isEditable; 1442a4207fb39330e840436215c896cde911489e111Paul Soulos mEntryContextMenuInfo = entryContextMenuInfo; 14548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mThirdIcon = thirdIcon; 14648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mThirdIntent = thirdIntent; 14748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mThirdContentDescription = thirdContentDescription; 1485f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn mThirdAction = thirdAction; 1495f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn mThirdExtras = thirdExtras; 150d23de6146c23a27836a96e8a6f10a74346a905ddGary Mai mShouldApplyThirdIconColor = shouldApplyThirdIconColor; 15148290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos mIconResourceId = iconResourceId; 1522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getIcon() { 1552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIcon; 1562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos String getHeader() { 1592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mHeader; 1602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos String getSubHeader() { 1632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mSubHeader; 1642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getSubHeaderIcon() { 1672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mSubHeaderIcon; 1682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public String getText() { 1712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mText; 1722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getTextIcon() { 1752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mTextIcon; 1762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1787ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang Spannable getPrimaryContentDescription() { 17923e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos return mPrimaryContentDescription; 18023e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos } 18123e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos 1822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Intent getIntent() { 1832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIntent; 1842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 186dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable getAlternateIcon() { 187dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateIcon; 188dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 189dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 190dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Intent getAlternateIntent() { 191dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateIntent; 192dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 193dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 1945da55ff837f57a63b409cd495cc25f61ed6fd709Wenyi Wang Spannable getAlternateContentDescription() { 195dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateContentDescription; 196dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 197dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 19848ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos boolean shouldApplyColor() { 19948ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos return mShouldApplyColor; 20048ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos } 20148ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos 2022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos boolean isEditable() { 2032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIsEditable; 2042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 205ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos 2062ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos int getId() { 2072ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mId; 208ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos } 2092a4207fb39330e840436215c896cde911489e111Paul Soulos 2102a4207fb39330e840436215c896cde911489e111Paul Soulos EntryContextMenuInfo getEntryContextMenuInfo() { 2112a4207fb39330e840436215c896cde911489e111Paul Soulos return mEntryContextMenuInfo; 2122a4207fb39330e840436215c896cde911489e111Paul Soulos } 21348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 21448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos Drawable getThirdIcon() { 21548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdIcon; 21648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 21748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 21848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos Intent getThirdIntent() { 21948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdIntent; 22048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 22148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 22248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos String getThirdContentDescription() { 22348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdContentDescription; 22448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 22548290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos 22648290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos int getIconResourceId() { 22748290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos return mIconResourceId; 22848290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos } 2295f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn 2305f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn public int getThirdAction() { 2315f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn return mThirdAction; 2325f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn } 2335f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn 2345f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn public Bundle getThirdExtras() { 2355f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn return mThirdExtras; 2365f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn } 237d23de6146c23a27836a96e8a6f10a74346a905ddGary Mai 238d23de6146c23a27836a96e8a6f10a74346a905ddGary Mai boolean shouldApplyThirdIconColor() { 239d23de6146c23a27836a96e8a6f10a74346a905ddGary Mai return mShouldApplyThirdIconColor; 240d23de6146c23a27836a96e8a6f10a74346a905ddGary Mai } 2412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 243e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell public interface ExpandingEntryCardViewListener { 244e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell void onCollapse(int heightDelta); 245245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell void onExpand(); 246245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell void onExpandDone(); 247e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell } 248e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell 2492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private View mExpandCollapseButton; 2502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private TextView mExpandCollapseTextView; 2512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private TextView mTitleTextView; 2522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private OnClickListener mOnClickListener; 2532a4207fb39330e840436215c896cde911489e111Paul Soulos private OnCreateContextMenuListener mOnCreateContextMenuListener; 2542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private boolean mIsExpanded = false; 255691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos /** 256691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos * The max number of entries to show in a collapsed card. If there are less entries passed in, 257691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos * then they are all shown. 258691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos */ 2592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private int mCollapsedEntriesCount; 260e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell private ExpandingEntryCardViewListener mListener; 26160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private List<List<Entry>> mEntries; 26260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private int mNumEntries = 0; 26360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private boolean mAllEntriesInflated = false; 26460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private List<List<View>> mEntryViews; 2652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private LinearLayout mEntriesViewGroup; 266c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos private final ImageView mExpandCollapseArrow; 2672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private int mThemeColor; 2687b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos private ColorFilter mThemeColorFilter; 26989966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos private boolean mIsAlwaysExpanded; 2700cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos /** The ViewGroup to run the expand/collapse animation on */ 2710cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private ViewGroup mAnimationViewGroup; 27205287bf0cea303b93802a629aa883fb6322ca342Brian Attwell private final int mDividerLineHeightPixels; 273cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos /** 274cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos * List to hold the separators. This saves us from reconstructing every expand/collapse and 275cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos * provides a smoother animation. 276cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos */ 277cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos private List<View> mSeparators; 278ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos private LinearLayout mContainer; 2792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final OnClickListener mExpandCollapseButtonListener = new OnClickListener() { 2812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 2822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void onClick(View v) { 2832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mIsExpanded) { 2842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos collapse(); 2852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 2862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos expand(); 2872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos }; 2902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public ExpandingEntryCardView(Context context) { 2920d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell this(context, null); 2932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public ExpandingEntryCardView(Context context, AttributeSet attrs) { 2962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos super(context, attrs); 2972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos LayoutInflater inflater = LayoutInflater.from(context); 2982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos View expandingEntryCardView = inflater.inflate(R.layout.expanding_entry_card_view, this); 2992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup = (LinearLayout) 3002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos expandingEntryCardView.findViewById(R.id.content_area_linear_layout); 3012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTitleTextView = (TextView) expandingEntryCardView.findViewById(R.id.title); 302ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos mContainer = (LinearLayout) expandingEntryCardView.findViewById(R.id.container); 3037b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 3047b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseButton = inflater.inflate( 3057b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos R.layout.quickcontact_expanding_entry_card_button, this, false); 3067b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseTextView = (TextView) mExpandCollapseButton.findViewById(R.id.text); 307c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos mExpandCollapseArrow = (ImageView) mExpandCollapseButton.findViewById(R.id.arrow); 3087b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseButton.setOnClickListener(mExpandCollapseButtonListener); 30905287bf0cea303b93802a629aa883fb6322ca342Brian Attwell mDividerLineHeightPixels = getResources() 31005287bf0cea303b93802a629aa883fb6322ca342Brian Attwell .getDimensionPixelSize(R.dimen.divider_line_height); 3112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 3142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the Entry list to display. 3152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 3162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param entries The Entry list to display. 3172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 31860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos public void initialize(List<List<Entry>> entries, int numInitialVisibleEntries, 319139a03bd82f45338402e747154dd7b3d61bf1747yaolu boolean isExpanded, boolean isAlwaysExpanded, ExpandingEntryCardViewListener listener, 320139a03bd82f45338402e747154dd7b3d61bf1747yaolu ViewGroup animationViewGroup) { 3212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos LayoutInflater layoutInflater = LayoutInflater.from(getContext()); 3222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = isExpanded; 32389966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos mIsAlwaysExpanded = isAlwaysExpanded; 32489966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos // If isAlwaysExpanded is true, mIsExpanded should be true 32589966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos mIsExpanded |= mIsAlwaysExpanded; 32660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mEntryViews = new ArrayList<List<View>>(entries.size()); 3270d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell mEntries = entries; 3286095369885edcca566a812b551886e29c7ff8039Brian Attwell mNumEntries = 0; 3296095369885edcca566a812b551886e29c7ff8039Brian Attwell mAllEntriesInflated = false; 33060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<Entry> entryList : mEntries) { 33160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mNumEntries += entryList.size(); 33260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mEntryViews.add(new ArrayList<View>()); 33360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 33460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mCollapsedEntriesCount = Math.min(numInitialVisibleEntries, mNumEntries); 335cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos // We need a separator between each list, but not after the last one 336cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (entries.size() > 1) { 337cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators = new ArrayList<>(entries.size() - 1); 338cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 339e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell mListener = listener; 3400cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mAnimationViewGroup = animationViewGroup; 3410d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell 3427b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mIsExpanded) { 343c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getCollapseButtonText(), /* duration = */ 0); 34460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(layoutInflater); 3457b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } else { 346c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getExpandButtonText(), /* duration = */ 0); 34760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateInitialEntries(layoutInflater); 3482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos insertEntriesIntoViewGroup(); 3507b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos applyColor(); 3512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 3542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setOnClickListener(OnClickListener listener) { 3552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mOnClickListener = listener; 3562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3582a4207fb39330e840436215c896cde911489e111Paul Soulos @Override 3592a4207fb39330e840436215c896cde911489e111Paul Soulos public void setOnCreateContextMenuListener (OnCreateContextMenuListener listener) { 3602a4207fb39330e840436215c896cde911489e111Paul Soulos mOnCreateContextMenuListener = listener; 3612a4207fb39330e840436215c896cde911489e111Paul Soulos } 3622a4207fb39330e840436215c896cde911489e111Paul Soulos 363245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell private List<View> calculateEntriesToRemoveDuringCollapse() { 364245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell final List<View> viewsToRemove = getViewsToDisplay(true); 365245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell final List<View> viewsCollapsed = getViewsToDisplay(false); 366245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell viewsToRemove.removeAll(viewsCollapsed); 367245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell return viewsToRemove; 368245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell } 369245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell 3702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void insertEntriesIntoViewGroup() { 3712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup.removeAllViews(); 37260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos 373245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell for (View view : getViewsToDisplay(mIsExpanded)) { 374245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell mEntriesViewGroup.addView(view); 375245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell } 376245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell 377245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell removeView(mExpandCollapseButton); 378245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell if (mCollapsedEntriesCount < mNumEntries 379245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell && mExpandCollapseButton.getParent() == null && !mIsAlwaysExpanded) { 380245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell mContainer.addView(mExpandCollapseButton, -1); 381245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell } 382245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell } 383245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell 384245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell /** 385245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell * Returns the list of views that should be displayed. This changes depending on whether 386245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell * the card is expanded or collapsed. 387245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell */ 388245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell private List<View> getViewsToDisplay(boolean isExpanded) { 389245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell final List<View> viewsToDisplay = new ArrayList<View>(); 390245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell if (isExpanded) { 391cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos for (int i = 0; i < mEntryViews.size(); i++) { 392cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos List<View> viewList = mEntryViews.get(i); 393cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (i > 0) { 394cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos View separator; 395cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (mSeparators.size() <= i - 1) { 396cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = generateSeparator(viewList.get(0)); 397cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators.add(separator); 398cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } else { 399cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = mSeparators.get(i - 1); 400cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 401245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell viewsToDisplay.add(separator); 40297ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 40360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (View view : viewList) { 404245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell viewsToDisplay.add(view); 40560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 40660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 40760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } else { 408691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // We want to insert mCollapsedEntriesCount entries into the group. extraEntries is the 409691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // number of entries that need to be added that are not the head element of a list 410691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // to reach mCollapsedEntriesCount. 411691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int numInViewGroup = 0; 412691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int extraEntries = mCollapsedEntriesCount - mEntryViews.size(); 413691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int i = 0; i < mEntryViews.size() && numInViewGroup < mCollapsedEntriesCount; 414691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos i++) { 415691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<View> entryViewList = mEntryViews.get(i); 41697ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (i > 0) { 417cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos View separator; 418cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (mSeparators.size() <= i - 1) { 419cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = generateSeparator(entryViewList.get(0)); 420cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators.add(separator); 421cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } else { 422cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = mSeparators.get(i - 1); 423cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 424245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell viewsToDisplay.add(separator); 425691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos } 426245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell viewsToDisplay.add(entryViewList.get(0)); 427691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInViewGroup++; 42805287bf0cea303b93802a629aa883fb6322ca342Brian Attwell 429691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // Insert entries in this list to hit mCollapsedEntriesCount. 430139a03bd82f45338402e747154dd7b3d61bf1747yaolu for (int j = 1; j < entryViewList.size() && numInViewGroup < mCollapsedEntriesCount 431139a03bd82f45338402e747154dd7b3d61bf1747yaolu && extraEntries > 0; j++) { 432245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell viewsToDisplay.add(entryViewList.get(j)); 433691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInViewGroup++; 434691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries--; 43597ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 4362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 439245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell formatEntryIfFirst(viewsToDisplay); 440245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell return viewsToDisplay; 4412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 443245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell private void formatEntryIfFirst(List<View> entriesViewGroup) { 4441321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // If no title and the first entry in the group, add extra padding 4451321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos if (TextUtils.isEmpty(mTitleTextView.getText()) && 446245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell entriesViewGroup.size() > 0) { 447245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell final View entry = entriesViewGroup.get(0); 4487c6c48ab12ce4dabe4609db847e747f6629d47e8yaolu entry.setPaddingRelative(entry.getPaddingStart(), 449568d5d82610f87a5e733690e57075f0a99551972Paul Soulos getResources().getDimensionPixelSize( 450568d5d82610f87a5e733690e57075f0a99551972Paul Soulos R.dimen.expanding_entry_card_item_padding_top) + 451568d5d82610f87a5e733690e57075f0a99551972Paul Soulos getResources().getDimensionPixelSize( 4521321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_null_title_top_extra_padding), 4537c6c48ab12ce4dabe4609db847e747f6629d47e8yaolu entry.getPaddingEnd(), 4541321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos entry.getPaddingBottom()); 4551321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } 4562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 458cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos private View generateSeparator(View entry) { 4590cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos View separator = new View(getContext()); 460ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos Resources res = getResources(); 461ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos 462ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos separator.setBackgroundColor(res.getColor( 463daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell R.color.divider_line_color_light)); 464ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 46505287bf0cea303b93802a629aa883fb6322ca342Brian Attwell ViewGroup.LayoutParams.MATCH_PARENT, mDividerLineHeightPixels); 4660cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // The separator is aligned with the text in the entry. This is offset by a default 4670cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // margin. If there is an icon present, the icon's width and margin are added 468ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos int marginStart = res.getDimensionPixelSize( 4690cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos R.dimen.expanding_entry_card_item_padding_start); 4700cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ImageView entryIcon = (ImageView) entry.findViewById(R.id.icon); 47197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (entryIcon.getVisibility() == View.VISIBLE) { 4720cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos int imageWidthAndMargin = 473ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_icon_width) + 474ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_image_spacing); 4750cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos marginStart += imageWidthAndMargin; 4760cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 47797ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos layoutParams.setMarginStart(marginStart); 4780cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos separator.setLayoutParams(layoutParams); 479cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos return separator; 4800cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 4810cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 4822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence getExpandButtonText() { 483139a03bd82f45338402e747154dd7b3d61bf1747yaolu // Default to "See more". 484139a03bd82f45338402e747154dd7b3d61bf1747yaolu return getResources().getText(R.string.expanding_entry_card_view_see_more); 4852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence getCollapseButtonText() { 488139a03bd82f45338402e747154dd7b3d61bf1747yaolu // Default to "See less". 489139a03bd82f45338402e747154dd7b3d61bf1747yaolu return getResources().getText(R.string.expanding_entry_card_view_see_less); 4902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4920d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell /** 49360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos * Inflates the initial entries to be shown. 4940d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell */ 49560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private void inflateInitialEntries(LayoutInflater layoutInflater) { 49660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // If the number of collapsed entries equals total entries, inflate all 49760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mCollapsedEntriesCount == mNumEntries) { 49860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(layoutInflater); 49960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } else { 50060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // Otherwise inflate the top entry from each list 501691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // extraEntries is used to add extra entries until mCollapsedEntriesCount is reached. 502691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int numInflated = 0; 503691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int extraEntries = mCollapsedEntriesCount - mEntries.size(); 504691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int i = 0; i < mEntries.size() && numInflated < mCollapsedEntriesCount; i++) { 505691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<Entry> entryList = mEntries.get(i); 506691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<View> entryViewList = mEntryViews.get(i); 507691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos 508691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos entryViewList.add(createEntryView(layoutInflater, entryList.get(0), 50997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos /* showIcon = */ View.VISIBLE)); 510691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInflated++; 51105287bf0cea303b93802a629aa883fb6322ca342Brian Attwell 512691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // Inflate entries in this list to hit mCollapsedEntriesCount. 513139a03bd82f45338402e747154dd7b3d61bf1747yaolu for (int j = 1; j < entryList.size() && numInflated < mCollapsedEntriesCount 51405287bf0cea303b93802a629aa883fb6322ca342Brian Attwell && extraEntries > 0; j++) { 515691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos entryViewList.add(createEntryView(layoutInflater, entryList.get(j), 51643e0dead719568ed610f9f111f6e7614368445efPaul Soulos /* showIcon = */ View.INVISIBLE)); 517691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInflated++; 518691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries--; 519691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos } 52060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 52160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 52260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 52360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos 52460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos /** 52560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos * Inflates all entries. 52660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos */ 52760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private void inflateAllEntries(LayoutInflater layoutInflater) { 52860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mAllEntriesInflated) { 52960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos return; 53060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 53160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int i = 0; i < mEntries.size(); i++) { 53260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos List<Entry> entryList = mEntries.get(i); 53360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos List<View> viewList = mEntryViews.get(i); 53460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int j = viewList.size(); j < entryList.size(); j++) { 53597ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos final int iconVisibility; 53697ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos final Entry entry = entryList.get(j); 53797ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos // If the entry does not have an icon, mark gone. Else if it has an icon, show 53897ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos // for the first Entry in the list only 53997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (entry.getIcon() == null) { 54097ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.GONE; 54197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } else if (j == 0) { 54297ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.VISIBLE; 54397ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } else { 54497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.INVISIBLE; 54597ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 54697ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos viewList.add(createEntryView(layoutInflater, entry, iconVisibility)); 54760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 5482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 54960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mAllEntriesInflated = true; 5502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 5527b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos public void setColorAndFilter(int color, ColorFilter colorFilter) { 5537b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mThemeColor = color; 5547b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mThemeColorFilter = colorFilter; 5557b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos applyColor(); 5567b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5577b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5586095369885edcca566a812b551886e29c7ff8039Brian Attwell public void setEntryHeaderColor(int color) { 5596095369885edcca566a812b551886e29c7ff8039Brian Attwell if (mEntries != null) { 5606095369885edcca566a812b551886e29c7ff8039Brian Attwell for (List<View> entryList : mEntryViews) { 5616095369885edcca566a812b551886e29c7ff8039Brian Attwell for (View entryView : entryList) { 5626095369885edcca566a812b551886e29c7ff8039Brian Attwell TextView header = (TextView) entryView.findViewById(R.id.header); 5636095369885edcca566a812b551886e29c7ff8039Brian Attwell if (header != null) { 5646095369885edcca566a812b551886e29c7ff8039Brian Attwell header.setTextColor(color); 5656095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5666095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5676095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5686095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5696095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5706095369885edcca566a812b551886e29c7ff8039Brian Attwell 57104a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu public void setEntrySubHeaderColor(int color) { 57204a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu if (mEntries != null) { 57304a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu for (List<View> entryList : mEntryViews) { 57404a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu for (View entryView : entryList) { 57504a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu final TextView subHeader = (TextView) entryView.findViewById(R.id.sub_header); 57604a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu if (subHeader != null) { 57704a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu subHeader.setTextColor(color); 57804a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu } 57904a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu } 58004a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu } 58104a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu } 58204a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu } 58304a1936c4f1f9f414551047c68e7a344d22fddc1guanxiongliu 5847b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos /** 5857b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * The ColorFilter is passed in along with the color so that a new one only needs to be created 5867b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * once for the entire activity. 5877b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 1. Title 5887b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 2. Entry icons 5897b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 3. Expand/Collapse Text 5907b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 4. Expand/Collapse Button 5917b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos */ 5927b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos public void applyColor() { 5937b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mThemeColor != 0 && mThemeColorFilter != null) { 5947b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Title 5957b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mTitleTextView != null) { 5967b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mTitleTextView.setTextColor(mThemeColor); 5977b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5987b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5997b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Entry icons 6007b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mEntries != null) { 60160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<Entry> entryList : mEntries) { 60260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (Entry entry : entryList) { 60348ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos if (entry.shouldApplyColor()) { 60448ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos Drawable icon = entry.getIcon(); 60548ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos if (icon != null) { 6060da93008e49306e99a90b114b7f8a60c78774fc3Brian Attwell icon.mutate(); 60748ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos icon.setColorFilter(mThemeColorFilter); 60848ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos } 60960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 610dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable alternateIcon = entry.getAlternateIcon(); 611dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos if (alternateIcon != null) { 6120da93008e49306e99a90b114b7f8a60c78774fc3Brian Attwell alternateIcon.mutate(); 613dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setColorFilter(mThemeColorFilter); 614dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 61548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos Drawable thirdIcon = entry.getThirdIcon(); 616d23de6146c23a27836a96e8a6f10a74346a905ddGary Mai if (thirdIcon != null && entry.shouldApplyThirdIconColor()) { 6170da93008e49306e99a90b114b7f8a60c78774fc3Brian Attwell thirdIcon.mutate(); 61848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setColorFilter(mThemeColorFilter); 61948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 620eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 6217b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 6227b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 6237b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 6247b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Expand/Collapse 6257b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseTextView.setTextColor(mThemeColor); 626c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos mExpandCollapseArrow.setColorFilter(mThemeColorFilter); 6277b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 6287b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 6297b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 6302a4207fb39330e840436215c896cde911489e111Paul Soulos private View createEntryView(LayoutInflater layoutInflater, final Entry entry, 6312a4207fb39330e840436215c896cde911489e111Paul Soulos int iconVisibility) { 6322a4207fb39330e840436215c896cde911489e111Paul Soulos final EntryView view = (EntryView) layoutInflater.inflate( 6332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos R.layout.expanding_entry_card_item, this, false); 6342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6352a4207fb39330e840436215c896cde911489e111Paul Soulos view.setContextMenuInfo(entry.getEntryContextMenuInfo()); 63623e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos if (!TextUtils.isEmpty(entry.getPrimaryContentDescription())) { 63723e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos view.setContentDescription(entry.getPrimaryContentDescription()); 63823e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos } 639ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos 640dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView icon = (ImageView) view.findViewById(R.id.icon); 64197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos icon.setVisibility(iconVisibility); 642eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos if (entry.getIcon() != null) { 643eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos icon.setImageDrawable(entry.getIcon()); 644eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 645dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView header = (TextView) view.findViewById(R.id.header); 64603ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getHeader())) { 6472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos header.setText(entry.getHeader()); 6482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos header.setVisibility(View.GONE); 6502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 652dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView subHeader = (TextView) view.findViewById(R.id.sub_header); 65303ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getSubHeader())) { 6542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeader.setText(entry.getSubHeader()); 6552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeader.setVisibility(View.GONE); 6572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 659dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header); 6602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getSubHeaderIcon() != null) { 6612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeaderIcon.setImageDrawable(entry.getSubHeaderIcon()); 6622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeaderIcon.setVisibility(View.GONE); 6642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 666dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView text = (TextView) view.findViewById(R.id.text); 66703ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getText())) { 6682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos text.setText(entry.getText()); 6692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos text.setVisibility(View.GONE); 6712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 673dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text); 6742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getTextIcon() != null) { 6752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos textIcon.setImageDrawable(entry.getTextIcon()); 6762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos textIcon.setVisibility(View.GONE); 6782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getIntent() != null) { 6817d22b94ce50f7a65dd89d4533f2aa3a3392e7972Paul Soulos view.setOnClickListener(mOnClickListener); 6822ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos view.setTag(new EntryTag(entry.getId(), entry.getIntent())); 6832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 685a42ef76251778161d27bc07db214b8c81720e476Paul Soulos if (entry.getIntent() == null && entry.getEntryContextMenuInfo() == null) { 686a42ef76251778161d27bc07db214b8c81720e476Paul Soulos // Remove the click effect 687a42ef76251778161d27bc07db214b8c81720e476Paul Soulos view.setBackground(null); 688a42ef76251778161d27bc07db214b8c81720e476Paul Soulos } 689a42ef76251778161d27bc07db214b8c81720e476Paul Soulos 690ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // If only the header is visible, add a top margin to match icon's top margin. 691ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // Also increase the space below the header for visual comfort. 6924b943553afdb7286b33e4bc2481431e816c57967Paul Soulos if (header.getVisibility() == View.VISIBLE && subHeader.getVisibility() == View.GONE && 6934b943553afdb7286b33e4bc2481431e816c57967Paul Soulos text.getVisibility() == View.GONE) { 6944b943553afdb7286b33e4bc2481431e816c57967Paul Soulos RelativeLayout.LayoutParams headerLayoutParams = 6954b943553afdb7286b33e4bc2481431e816c57967Paul Soulos (RelativeLayout.LayoutParams) header.getLayoutParams(); 6964b943553afdb7286b33e4bc2481431e816c57967Paul Soulos headerLayoutParams.topMargin = (int) (getResources().getDimension( 697ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos R.dimen.expanding_entry_card_item_header_only_margin_top)); 698ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos headerLayoutParams.bottomMargin += (int) (getResources().getDimension( 699ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos R.dimen.expanding_entry_card_item_header_only_margin_bottom)); 7004b943553afdb7286b33e4bc2481431e816c57967Paul Soulos header.setLayoutParams(headerLayoutParams); 7014b943553afdb7286b33e4bc2481431e816c57967Paul Soulos } 7024b943553afdb7286b33e4bc2481431e816c57967Paul Soulos 703edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos // Adjust the top padding size for entries with an invisible icon. The padding depends on 704edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos // if there is a sub header or text section 705edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos if (iconVisibility == View.INVISIBLE && 706edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos (!TextUtils.isEmpty(entry.getSubHeader()) || !TextUtils.isEmpty(entry.getText()))) { 707edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.setPaddingRelative(view.getPaddingStart(), 708edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos getResources().getDimensionPixelSize( 709edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos R.dimen.expanding_entry_card_item_no_icon_margin_top), 710edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.getPaddingEnd(), 711edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.getPaddingBottom()); 712edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos } else if (iconVisibility == View.INVISIBLE && TextUtils.isEmpty(entry.getSubHeader()) 713edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos && TextUtils.isEmpty(entry.getText())) { 714ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos view.setPaddingRelative(view.getPaddingStart(), 0, view.getPaddingEnd(), 715ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos view.getPaddingBottom()); 716ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos } 717ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos 71848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos final ImageView alternateIcon = (ImageView) view.findViewById(R.id.icon_alternate); 71948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos final ImageView thirdIcon = (ImageView) view.findViewById(R.id.third_icon); 72048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 72148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (entry.getAlternateIcon() != null && entry.getAlternateIntent() != null) { 72248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setImageDrawable(entry.getAlternateIcon()); 72348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setOnClickListener(mOnClickListener); 72448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setTag(new EntryTag(entry.getId(), entry.getAlternateIntent())); 72548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setVisibility(View.VISIBLE); 72648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setContentDescription(entry.getAlternateContentDescription()); 72748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 72848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 7295f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn if (entry.getThirdIcon() != null && entry.getThirdAction() != Entry.ACTION_NONE) { 73048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setImageDrawable(entry.getThirdIcon()); 7315f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn if (entry.getThirdAction() == Entry.ACTION_INTENT) { 7325f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn thirdIcon.setOnClickListener(mOnClickListener); 7335f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn thirdIcon.setTag(new EntryTag(entry.getId(), entry.getThirdIntent())); 7345f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn } else if (entry.getThirdAction() == Entry.ACTION_CALL_WITH_SUBJECT) { 7355f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn thirdIcon.setOnClickListener(new View.OnClickListener() { 7365f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn @Override 7375f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn public void onClick(View v) { 7385f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn Object tag = v.getTag(); 7395f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn if (!(tag instanceof Bundle)) { 7405f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn return; 7415f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn } 7425f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn 7435f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn Context context = getContext(); 7445f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn if (context instanceof Activity) { 7455f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn CallSubjectDialog.start((Activity) context, entry.getThirdExtras()); 7465f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn } 7475f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn } 7485f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn }); 7495f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn thirdIcon.setTag(entry.getThirdExtras()); 7505f87e923b0300173ad68f73a47b0dca7348d6a1fTyler Gunn } 75148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setVisibility(View.VISIBLE); 75248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setContentDescription(entry.getThirdContentDescription()); 75348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 75448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 75548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos // Set a custom touch listener for expanding the extra icon touch areas 75648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos view.setOnTouchListener(new EntryTouchListener(view, alternateIcon, thirdIcon)); 7572a4207fb39330e840436215c896cde911489e111Paul Soulos view.setOnCreateContextMenuListener(mOnCreateContextMenuListener); 7582a4207fb39330e840436215c896cde911489e111Paul Soulos 7592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return view; 7602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 762c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos private void updateExpandCollapseButton(CharSequence buttonText, long duration) { 763c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos if (mIsExpanded) { 764c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos final ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandCollapseArrow, 765c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos "rotation", 180); 766c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.setDuration(duration); 767c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.start(); 7682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 769c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos final ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandCollapseArrow, 770c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos "rotation", 0); 771c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.setDuration(duration); 772c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.start(); 7732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(buttonText); 7752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void expand() { 7780cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ChangeBounds boundsTransition = new ChangeBounds(); 7790cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.setDuration(DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS); 7800cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7810cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos Fade fadeIn = new Fade(Fade.IN); 7820cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos fadeIn.setDuration(DURATION_EXPAND_ANIMATION_FADE_IN); 7830cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos fadeIn.setStartDelay(DELAY_EXPAND_ANIMATION_FADE_IN); 7840cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7850cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionSet transitionSet = new TransitionSet(); 7860cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(boundsTransition); 7870cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(fadeIn); 7880cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7894cd9ed68dca5f4adeb8ec2065526c18f33af5926Paul Soulos transitionSet.excludeTarget(R.id.text, /* exclude = */ true); 7904cd9ed68dca5f4adeb8ec2065526c18f33af5926Paul Soulos 7910cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ViewGroup transitionViewContainer = mAnimationViewGroup == null ? 7920cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos this : mAnimationViewGroup; 7930cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7940cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addListener(new TransitionListener() { 7950cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7960cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionStart(Transition transition) { 797245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell mListener.onExpand(); 7980cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7990cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8000cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8010cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionEnd(Transition transition) { 802245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell mListener.onExpandDone(); 8030cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8040cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8050cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8060cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionCancel(Transition transition) { 8070cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8080cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8090cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8100cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionPause(Transition transition) { 8110cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8120cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8130cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8140cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionResume(Transition transition) { 8150cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8160cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos }); 8170cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8180cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet); 8192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = true; 8210d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell // In order to insert new entries, we may need to inflate them for the first time 82260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(LayoutInflater.from(getContext())); 8232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos insertEntriesIntoViewGroup(); 824c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getCollapseButtonText(), 825c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS); 8262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void collapse() { 829245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell final List<View> views = calculateEntriesToRemoveDuringCollapse(); 830245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell 831245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell // This animation requires layout changes, unlike the expand() animation: the action bar 832245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell // might get scrolled open in order to fill empty space. As a result, we can't use 833245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell // ChangeBounds here. Instead manually animate view height and alpha. This isn't as 834245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell // efficient as the bounds and translation changes performed by ChangeBounds. Nonetheless, a 835245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell // reasonable frame-rate is achieved collapsing a dozen elements on a user Svelte N4. So the 836245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell // performance hit doesn't justify writing a less maintainable animation. 837245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell final AnimatorSet set = new AnimatorSet(); 838245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell final List<Animator> animators = new ArrayList<Animator>(views.size()); 839245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell int totalSizeChange = 0; 840245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell for (View viewToRemove : views) { 841245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell final ObjectAnimator animator = ObjectAnimator.ofObject(viewToRemove, 842245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell VIEW_LAYOUT_HEIGHT_PROPERTY, null, viewToRemove.getHeight(), 0); 843245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell totalSizeChange += viewToRemove.getHeight(); 844245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell animator.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 845245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell animators.add(animator); 846245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell viewToRemove.animate().alpha(0).setDuration(DURATION_COLLAPSE_ANIMATION_FADE_OUT); 847245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell } 848245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell set.playTogether(animators); 849245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell set.start(); 850245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell set.addListener(new AnimatorListener() { 8510cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 852245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell public void onAnimationStart(Animator animation) { 8530cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8540cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 856245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell public void onAnimationEnd(Animator animation) { 857245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell // Now that the views have been animated away, actually remove them from the view 858245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell // hierarchy. Reset their appearance so that they look appropriate when they 85905287bf0cea303b93802a629aa883fb6322ca342Brian Attwell // get added back later. 860245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell insertEntriesIntoViewGroup(); 861245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell for (View view : views) { 86205287bf0cea303b93802a629aa883fb6322ca342Brian Attwell if (view instanceof EntryView) { 86305287bf0cea303b93802a629aa883fb6322ca342Brian Attwell VIEW_LAYOUT_HEIGHT_PROPERTY.set(view, LayoutParams.WRAP_CONTENT); 86405287bf0cea303b93802a629aa883fb6322ca342Brian Attwell } else { 86505287bf0cea303b93802a629aa883fb6322ca342Brian Attwell VIEW_LAYOUT_HEIGHT_PROPERTY.set(view, mDividerLineHeightPixels); 86605287bf0cea303b93802a629aa883fb6322ca342Brian Attwell } 867245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell view.animate().cancel(); 868245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell view.setAlpha(1); 869245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell } 8700cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8710cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8720cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 873245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell public void onAnimationCancel(Animator animation) { 8740cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8750cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8760cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 877245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell public void onAnimationRepeat(Animator animation) { 8782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos }); 8800cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 881245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell mListener.onCollapse(totalSizeChange); 882245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell mIsExpanded = false; 883245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell updateExpandCollapseButton(getExpandButtonText(), 884245d3d2000150cbb21111370f42addaeeb1b10a0Brian Attwell DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 8852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 8882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Returns whether the view is currently in its expanded state. 8892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 8902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public boolean isExpanded() { 8912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIsExpanded; 8922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 8952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the title text of this ExpandingEntryCardView. 8962fa690807a94708384789b211965bfc75b5ac38ePaul Soulos * @param title The title to set. A null title will result in the title being removed. 8972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 8982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setTitle(String title) { 8992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mTitleTextView == null) { 9002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Log.e(TAG, "mTitleTextView is null"); 9012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 9022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTitleTextView.setText(title); 9031321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos mTitleTextView.setVisibility(TextUtils.isEmpty(title) ? View.GONE : View.VISIBLE); 9041321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos findViewById(R.id.title_separator).setVisibility(TextUtils.isEmpty(title) ? 9051321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View.GONE : View.VISIBLE); 9061321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // If the title is set after children have been added, reset the top entry's padding to 9071321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // the default. Else if the title is cleared after children have been added, set 9081321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // the extra top padding 9091321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos if (!TextUtils.isEmpty(title) && mEntriesViewGroup.getChildCount() > 0) { 9101321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View firstEntry = mEntriesViewGroup.getChildAt(0); 9111321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.setPadding(firstEntry.getPaddingLeft(), 9121321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 9131321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_item_padding_top), 9141321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingRight(), 9151321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingBottom()); 9161321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } else if (!TextUtils.isEmpty(title) && mEntriesViewGroup.getChildCount() > 0) { 9171321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View firstEntry = mEntriesViewGroup.getChildAt(0); 9181321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.setPadding(firstEntry.getPaddingLeft(), 9191321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 9201321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_item_padding_top) + 9211321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 9221321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_null_title_top_extra_padding), 9231321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingRight(), 9248897287c19b394c1f0b402e6291ff4304acacbc2Brian Attwell firstEntry.getPaddingBottom()); 9251321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } 9262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 927eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos 928eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos public boolean shouldShow() { 929eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos return mEntries != null && mEntries.size() > 0; 930eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 9312a4207fb39330e840436215c896cde911489e111Paul Soulos 9322a4207fb39330e840436215c896cde911489e111Paul Soulos public static final class EntryView extends RelativeLayout { 9332a4207fb39330e840436215c896cde911489e111Paul Soulos private EntryContextMenuInfo mEntryContextMenuInfo; 9342a4207fb39330e840436215c896cde911489e111Paul Soulos 9352a4207fb39330e840436215c896cde911489e111Paul Soulos public EntryView(Context context) { 9362a4207fb39330e840436215c896cde911489e111Paul Soulos super(context); 9372a4207fb39330e840436215c896cde911489e111Paul Soulos } 9382a4207fb39330e840436215c896cde911489e111Paul Soulos 9392a4207fb39330e840436215c896cde911489e111Paul Soulos public EntryView(Context context, AttributeSet attrs) { 9402a4207fb39330e840436215c896cde911489e111Paul Soulos super(context, attrs); 9412a4207fb39330e840436215c896cde911489e111Paul Soulos } 9422a4207fb39330e840436215c896cde911489e111Paul Soulos 9432a4207fb39330e840436215c896cde911489e111Paul Soulos public void setContextMenuInfo(EntryContextMenuInfo info) { 9442a4207fb39330e840436215c896cde911489e111Paul Soulos mEntryContextMenuInfo = info; 9452a4207fb39330e840436215c896cde911489e111Paul Soulos } 9462a4207fb39330e840436215c896cde911489e111Paul Soulos 9472a4207fb39330e840436215c896cde911489e111Paul Soulos @Override 9482a4207fb39330e840436215c896cde911489e111Paul Soulos protected ContextMenuInfo getContextMenuInfo() { 9492a4207fb39330e840436215c896cde911489e111Paul Soulos return mEntryContextMenuInfo; 9502a4207fb39330e840436215c896cde911489e111Paul Soulos } 9512a4207fb39330e840436215c896cde911489e111Paul Soulos } 9522a4207fb39330e840436215c896cde911489e111Paul Soulos 9532a4207fb39330e840436215c896cde911489e111Paul Soulos public static final class EntryContextMenuInfo implements ContextMenuInfo { 9542a4207fb39330e840436215c896cde911489e111Paul Soulos private final String mCopyText; 9552a4207fb39330e840436215c896cde911489e111Paul Soulos private final String mCopyLabel; 95697f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos private final String mMimeType; 95797f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos private final long mId; 95897f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos private final boolean mIsSuperPrimary; 9592a4207fb39330e840436215c896cde911489e111Paul Soulos 96097f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos public EntryContextMenuInfo(String copyText, String copyLabel, String mimeType, long id, 96197f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos boolean isSuperPrimary) { 9622a4207fb39330e840436215c896cde911489e111Paul Soulos mCopyText = copyText; 9632a4207fb39330e840436215c896cde911489e111Paul Soulos mCopyLabel = copyLabel; 96497f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos mMimeType = mimeType; 96597f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos mId = id; 96697f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos mIsSuperPrimary = isSuperPrimary; 9672a4207fb39330e840436215c896cde911489e111Paul Soulos } 9682a4207fb39330e840436215c896cde911489e111Paul Soulos 9692a4207fb39330e840436215c896cde911489e111Paul Soulos public String getCopyText() { 9702a4207fb39330e840436215c896cde911489e111Paul Soulos return mCopyText; 9712a4207fb39330e840436215c896cde911489e111Paul Soulos } 9722a4207fb39330e840436215c896cde911489e111Paul Soulos 9732a4207fb39330e840436215c896cde911489e111Paul Soulos public String getCopyLabel() { 9742a4207fb39330e840436215c896cde911489e111Paul Soulos return mCopyLabel; 9752a4207fb39330e840436215c896cde911489e111Paul Soulos } 97697f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos 97797f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos public String getMimeType() { 97897f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos return mMimeType; 97997f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos } 98097f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos 98197f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos public long getId() { 98297f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos return mId; 98397f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos } 98497f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos 98597f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos public boolean isSuperPrimary() { 98697f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos return mIsSuperPrimary; 98797f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos } 9882a4207fb39330e840436215c896cde911489e111Paul Soulos } 9892ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9902ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos static final class EntryTag { 9912ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos private final int mId; 9922ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos private final Intent mIntent; 9932ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9942ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public EntryTag(int id, Intent intent) { 9952ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mId = id; 9962ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mIntent = intent; 9972ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 9982ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9992ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public int getId() { 10002ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mId; 10012ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 10022ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 10032ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public Intent getIntent() { 10042ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mIntent; 10052ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 10062ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 100748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 100848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos /** 100948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos * This custom touch listener increases the touch area for the second and third icons, if 101048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos * they are present. This is necessary to maintain other properties on an entry view, like 101148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos * using a top padding on entry. Based off of {@link android.view.TouchDelegate} 101248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos */ 101348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private static final class EntryTouchListener implements View.OnTouchListener { 101448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final View mEntry; 101548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final ImageView mAlternateIcon; 101648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final ImageView mThirdIcon; 101748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos /** mTouchedView locks in a view on touch down */ 101848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private View mTouchedView; 101948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos /** mSlop adds some space to account for touches that are just outside the hit area */ 102048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private int mSlop; 102148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 102248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos public EntryTouchListener(View entry, ImageView alternateIcon, ImageView thirdIcon) { 102348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mEntry = entry; 102448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mAlternateIcon = alternateIcon; 102548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mThirdIcon = thirdIcon; 102648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mSlop = ViewConfiguration.get(entry.getContext()).getScaledTouchSlop(); 102748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 102848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 102948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos @Override 103048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos public boolean onTouch(View v, MotionEvent event) { 103148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos View touchedView = mTouchedView; 103248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos boolean sendToTouched = false; 103348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos boolean hit = true; 103448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos boolean handled = false; 103548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 103648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos switch (event.getAction()) { 103748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos case MotionEvent.ACTION_DOWN: 103848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (hitThirdIcon(event)) { 103948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mTouchedView = mThirdIcon; 104048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = true; 104148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else if (hitAlternateIcon(event)) { 104248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mTouchedView = mAlternateIcon; 104348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = true; 104448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else { 104548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mTouchedView = mEntry; 104648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = false; 104748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 104848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos touchedView = mTouchedView; 104948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos break; 105048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos case MotionEvent.ACTION_UP: 105148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos case MotionEvent.ACTION_MOVE: 105248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = mTouchedView != null && mTouchedView != mEntry; 105348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (sendToTouched) { 105448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos final Rect slopBounds = new Rect(); 105548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos touchedView.getHitRect(slopBounds); 105648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos slopBounds.inset(-mSlop, -mSlop); 105748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (!slopBounds.contains((int) event.getX(), (int) event.getY())) { 105848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos hit = false; 105948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 106048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 106148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos break; 106248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos case MotionEvent.ACTION_CANCEL: 106348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = mTouchedView != null && mTouchedView != mEntry; 106448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mTouchedView = null; 106548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos break; 106648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 106748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (sendToTouched) { 106848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (hit) { 106948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.setLocation(touchedView.getWidth() / 2, touchedView.getHeight() / 2); 107048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else { 107148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos // Offset event coordinates to be outside the target view (in case it does 107248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos // something like tracking pressed state) 107348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.setLocation(-(mSlop * 2), -(mSlop * 2)); 107448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 107548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos handled = touchedView.dispatchTouchEvent(event); 107648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 107748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return handled; 107848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 107948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 108048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private boolean hitThirdIcon(MotionEvent event) { 1081f140227beb6d9e78955a7676dc0dd3f793f72017Brian Attwell if (mEntry.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { 108248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdIcon.getVisibility() == View.VISIBLE && 108348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.getX() < mThirdIcon.getRight(); 108448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else { 108548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdIcon.getVisibility() == View.VISIBLE && 108648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.getX() > mThirdIcon.getLeft(); 108748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 108848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 108948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 109048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos /** 109148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos * Should be used after checking if third icon was hit 109248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos */ 109348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private boolean hitAlternateIcon(MotionEvent event) { 109448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos // LayoutParams used to add the start margin to the touch area 109548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos final RelativeLayout.LayoutParams alternateIconParams = 109648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos (RelativeLayout.LayoutParams) mAlternateIcon.getLayoutParams(); 1097f140227beb6d9e78955a7676dc0dd3f793f72017Brian Attwell if (mEntry.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { 109848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mAlternateIcon.getVisibility() == View.VISIBLE && 109948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.getX() < mAlternateIcon.getRight() + alternateIconParams.rightMargin; 110048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else { 110148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mAlternateIcon.getVisibility() == View.VISIBLE && 110248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.getX() > mAlternateIcon.getLeft() - alternateIconParams.leftMargin; 110348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 110448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 110548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 11062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos} 1107