ExpandingEntryCardView.java revision 7ce5352a70e8aaf120bf4f7bd05d595f46abb080
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 18c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulosimport android.animation.ObjectAnimator; 192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.Context; 202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.Intent; 212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.res.Resources; 227b0b0ce616c6c2fa149918c112128388712f5657Paul Soulosimport android.graphics.ColorFilter; 23dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulosimport android.graphics.Rect; 242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.graphics.drawable.Drawable; 25ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulosimport android.support.v7.widget.CardView; 267ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jangimport android.text.Spannable; 272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.text.TextUtils; 280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.ChangeBounds; 290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.ChangeScroll; 300cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Fade; 310cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Transition; 320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Transition.TransitionListener; 330cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.TransitionManager; 340cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.TransitionSet; 352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.AttributeSet; 362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.Log; 372a4207fb39330e840436215c896cde911489e111Paul Soulosimport android.view.ContextMenu.ContextMenuInfo; 382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.LayoutInflater; 3948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulosimport android.view.MotionEvent; 402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.View; 4148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulosimport android.view.ViewConfiguration; 422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.ViewGroup; 432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.ImageView; 442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.LinearLayout; 454b943553afdb7286b33e4bc2481431e816c57967Paul Soulosimport android.widget.RelativeLayout; 462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.TextView; 472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 480cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport com.android.contacts.R; 490cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.ArrayList; 512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.List; 522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos/** 542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Display entries in a LinearLayout that can be expanded to show all entries. 552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 56ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulospublic class ExpandingEntryCardView extends CardView { 572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private static final String TAG = "ExpandingEntryCardView"; 590cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private static final int DURATION_EXPAND_ANIMATION_FADE_IN = 200; 600cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private static final int DELAY_EXPAND_ANIMATION_FADE_IN = 100; 610cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 620cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public static final int DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS = 300; 630cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public static final int DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS = 300; 642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Entry data. 672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public static final class Entry { 692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 702ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos private final int mId; 712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mIcon; 722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mHeader; 732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mSubHeader; 742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mSubHeaderIcon; 752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mText; 762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mTextIcon; 777ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang private Spannable mPrimaryContentDescription; 782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Intent mIntent; 79dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final Drawable mAlternateIcon; 80dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final Intent mAlternateIntent; 81dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final String mAlternateContentDescription; 8248ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos private final boolean mShouldApplyColor; 832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final boolean mIsEditable; 842a4207fb39330e840436215c896cde911489e111Paul Soulos private final EntryContextMenuInfo mEntryContextMenuInfo; 8548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final Drawable mThirdIcon; 8648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final Intent mThirdIntent; 8748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final String mThirdContentDescription; 8848290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos private final int mIconResourceId; 892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 902ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public Entry(int id, Drawable mainIcon, String header, String subHeader, 9123e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos Drawable subHeaderIcon, String text, Drawable textIcon, 927ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang Spannable primaryContentDescription, Intent intent, 93dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable alternateIcon, Intent alternateIntent, String alternateContentDescription, 942a4207fb39330e840436215c896cde911489e111Paul Soulos boolean shouldApplyColor, boolean isEditable, 9548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos EntryContextMenuInfo entryContextMenuInfo, Drawable thirdIcon, Intent thirdIntent, 9648290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos String thirdContentDescription, int iconResourceId) { 972ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mId = id; 982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIcon = mainIcon; 992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mHeader = header; 1002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mSubHeader = subHeader; 1012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mSubHeaderIcon = subHeaderIcon; 1022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mText = text; 1032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTextIcon = textIcon; 10423e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos mPrimaryContentDescription = primaryContentDescription; 1052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIntent = intent; 106dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateIcon = alternateIcon; 107dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateIntent = alternateIntent; 108dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateContentDescription = alternateContentDescription; 10948ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos mShouldApplyColor = shouldApplyColor; 1102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsEditable = isEditable; 1112a4207fb39330e840436215c896cde911489e111Paul Soulos mEntryContextMenuInfo = entryContextMenuInfo; 11248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mThirdIcon = thirdIcon; 11348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mThirdIntent = thirdIntent; 11448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mThirdContentDescription = thirdContentDescription; 11548290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos mIconResourceId = iconResourceId; 1162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getIcon() { 1192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIcon; 1202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos String getHeader() { 1232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mHeader; 1242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos String getSubHeader() { 1272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mSubHeader; 1282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getSubHeaderIcon() { 1312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mSubHeaderIcon; 1322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public String getText() { 1352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mText; 1362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getTextIcon() { 1392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mTextIcon; 1402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1427ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang Spannable getPrimaryContentDescription() { 14323e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos return mPrimaryContentDescription; 14423e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos } 14523e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos 1462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Intent getIntent() { 1472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIntent; 1482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 150dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable getAlternateIcon() { 151dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateIcon; 152dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 153dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 154dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Intent getAlternateIntent() { 155dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateIntent; 156dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 157dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 158dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos String getAlternateContentDescription() { 159dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateContentDescription; 160dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 161dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 16248ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos boolean shouldApplyColor() { 16348ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos return mShouldApplyColor; 16448ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos } 16548ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos 1662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos boolean isEditable() { 1672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIsEditable; 1682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 169ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos 1702ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos int getId() { 1712ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mId; 172ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos } 1732a4207fb39330e840436215c896cde911489e111Paul Soulos 1742a4207fb39330e840436215c896cde911489e111Paul Soulos EntryContextMenuInfo getEntryContextMenuInfo() { 1752a4207fb39330e840436215c896cde911489e111Paul Soulos return mEntryContextMenuInfo; 1762a4207fb39330e840436215c896cde911489e111Paul Soulos } 17748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 17848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos Drawable getThirdIcon() { 17948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdIcon; 18048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 18148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 18248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos Intent getThirdIntent() { 18348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdIntent; 18448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 18548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 18648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos String getThirdContentDescription() { 18748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdContentDescription; 18848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 18948290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos 19048290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos int getIconResourceId() { 19148290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos return mIconResourceId; 19248290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos } 1932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 195e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell public interface ExpandingEntryCardViewListener { 196e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell void onCollapse(int heightDelta); 1970cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos void onExpand(int heightDelta); 198e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell } 199e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell 2002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private View mExpandCollapseButton; 2012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private TextView mExpandCollapseTextView; 2022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private TextView mTitleTextView; 2032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence mExpandButtonText; 2042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence mCollapseButtonText; 2052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private OnClickListener mOnClickListener; 2062a4207fb39330e840436215c896cde911489e111Paul Soulos private OnCreateContextMenuListener mOnCreateContextMenuListener; 2072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private boolean mIsExpanded = false; 208691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos /** 209691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos * The max number of entries to show in a collapsed card. If there are less entries passed in, 210691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos * then they are all shown. 211691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos */ 2122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private int mCollapsedEntriesCount; 213e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell private ExpandingEntryCardViewListener mListener; 21460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private List<List<Entry>> mEntries; 21560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private int mNumEntries = 0; 21660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private boolean mAllEntriesInflated = false; 21760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private List<List<View>> mEntryViews; 2182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private LinearLayout mEntriesViewGroup; 219c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos private final ImageView mExpandCollapseArrow; 2202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private int mThemeColor; 2217b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos private ColorFilter mThemeColorFilter; 22289966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos private boolean mIsAlwaysExpanded; 2230cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos /** The ViewGroup to run the expand/collapse animation on */ 2240cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private ViewGroup mAnimationViewGroup; 2256b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private LinearLayout mBadgeContainer; 2266b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private final List<ImageView> mBadges; 22748290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos private final List<Integer> mBadgeIds; 228cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos /** 229cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos * List to hold the separators. This saves us from reconstructing every expand/collapse and 230cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos * provides a smoother animation. 231cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos */ 232cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos private List<View> mSeparators; 233ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos private LinearLayout mContainer; 2342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final OnClickListener mExpandCollapseButtonListener = new OnClickListener() { 2362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 2372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void onClick(View v) { 2382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mIsExpanded) { 2392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos collapse(); 2402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 2412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos expand(); 2422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos }; 2452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public ExpandingEntryCardView(Context context) { 2470d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell this(context, null); 2482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public ExpandingEntryCardView(Context context, AttributeSet attrs) { 2512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos super(context, attrs); 2522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos LayoutInflater inflater = LayoutInflater.from(context); 2532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos View expandingEntryCardView = inflater.inflate(R.layout.expanding_entry_card_view, this); 2542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup = (LinearLayout) 2552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos expandingEntryCardView.findViewById(R.id.content_area_linear_layout); 2562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTitleTextView = (TextView) expandingEntryCardView.findViewById(R.id.title); 257ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos mContainer = (LinearLayout) expandingEntryCardView.findViewById(R.id.container); 2587b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 2597b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseButton = inflater.inflate( 2607b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos R.layout.quickcontact_expanding_entry_card_button, this, false); 2617b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseTextView = (TextView) mExpandCollapseButton.findViewById(R.id.text); 262c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos mExpandCollapseArrow = (ImageView) mExpandCollapseButton.findViewById(R.id.arrow); 2637b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseButton.setOnClickListener(mExpandCollapseButtonListener); 2646b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer = (LinearLayout) mExpandCollapseButton.findViewById(R.id.badge_container); 2657b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 2666b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadges = new ArrayList<ImageView>(); 26748290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos mBadgeIds = new ArrayList<Integer>(); 2682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 2712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the Entry list to display. 2722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 2732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param entries The Entry list to display. 2742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 27560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos public void initialize(List<List<Entry>> entries, int numInitialVisibleEntries, 27689966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos boolean isExpanded, boolean isAlwaysExpanded, 2770cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ExpandingEntryCardViewListener listener, ViewGroup animationViewGroup) { 2782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos LayoutInflater layoutInflater = LayoutInflater.from(getContext()); 2792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = isExpanded; 28089966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos mIsAlwaysExpanded = isAlwaysExpanded; 28189966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos // If isAlwaysExpanded is true, mIsExpanded should be true 28289966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos mIsExpanded |= mIsAlwaysExpanded; 28360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mEntryViews = new ArrayList<List<View>>(entries.size()); 2840d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell mEntries = entries; 2856095369885edcca566a812b551886e29c7ff8039Brian Attwell mNumEntries = 0; 2866095369885edcca566a812b551886e29c7ff8039Brian Attwell mAllEntriesInflated = false; 28760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<Entry> entryList : mEntries) { 28860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mNumEntries += entryList.size(); 28960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mEntryViews.add(new ArrayList<View>()); 29060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 29160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mCollapsedEntriesCount = Math.min(numInitialVisibleEntries, mNumEntries); 292cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos // We need a separator between each list, but not after the last one 293cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (entries.size() > 1) { 294cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators = new ArrayList<>(entries.size() - 1); 295cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 296e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell mListener = listener; 2970cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mAnimationViewGroup = animationViewGroup; 2980d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell 2997b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mIsExpanded) { 300c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getCollapseButtonText(), /* duration = */ 0); 30160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(layoutInflater); 3027b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } else { 303c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getExpandButtonText(), /* duration = */ 0); 30460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateInitialEntries(layoutInflater); 3052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos insertEntriesIntoViewGroup(); 3077b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos applyColor(); 3082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 3112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the text for the expand button. 3122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 3132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param expandButtonText The expand button text. 3142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 3152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setExpandButtonText(CharSequence expandButtonText) { 3162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandButtonText = expandButtonText; 3172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mExpandCollapseTextView != null && !mIsExpanded) { 3182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(expandButtonText); 3192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 3232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the text for the expand button. 3242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 3252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param expandButtonText The expand button text. 3262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 3272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setCollapseButtonText(CharSequence expandButtonText) { 3282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mCollapseButtonText = expandButtonText; 3292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mExpandCollapseTextView != null && mIsExpanded) { 3302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(mCollapseButtonText); 3312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 3352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setOnClickListener(OnClickListener listener) { 3362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mOnClickListener = listener; 3372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3392a4207fb39330e840436215c896cde911489e111Paul Soulos @Override 3402a4207fb39330e840436215c896cde911489e111Paul Soulos public void setOnCreateContextMenuListener (OnCreateContextMenuListener listener) { 3412a4207fb39330e840436215c896cde911489e111Paul Soulos mOnCreateContextMenuListener = listener; 3422a4207fb39330e840436215c896cde911489e111Paul Soulos } 3432a4207fb39330e840436215c896cde911489e111Paul Soulos 3442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void insertEntriesIntoViewGroup() { 3452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup.removeAllViews(); 34660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos 3472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mIsExpanded) { 348cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos for (int i = 0; i < mEntryViews.size(); i++) { 349cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos List<View> viewList = mEntryViews.get(i); 350cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (i > 0) { 351cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos View separator; 352cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (mSeparators.size() <= i - 1) { 353cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = generateSeparator(viewList.get(0)); 354cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators.add(separator); 355cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } else { 356cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = mSeparators.get(i - 1); 357cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 358cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mEntriesViewGroup.addView(separator); 35997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 36060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (View view : viewList) { 36160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos addEntry(view); 36260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 36360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 36460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } else { 365691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // We want to insert mCollapsedEntriesCount entries into the group. extraEntries is the 366691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // number of entries that need to be added that are not the head element of a list 367691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // to reach mCollapsedEntriesCount. 368691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int numInViewGroup = 0; 369691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int extraEntries = mCollapsedEntriesCount - mEntryViews.size(); 370691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int i = 0; i < mEntryViews.size() && numInViewGroup < mCollapsedEntriesCount; 371691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos i++) { 372691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<View> entryViewList = mEntryViews.get(i); 37397ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (i > 0) { 374cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos View separator; 375cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (mSeparators.size() <= i - 1) { 376cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = generateSeparator(entryViewList.get(0)); 377cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators.add(separator); 378cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } else { 379cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = mSeparators.get(i - 1); 380cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 381cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mEntriesViewGroup.addView(separator); 382691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos } 383691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos addEntry(entryViewList.get(0)); 384691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInViewGroup++; 385691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // Insert entries in this list to hit mCollapsedEntriesCount. 386691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int j = 1; 387691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos j < entryViewList.size() && numInViewGroup < mCollapsedEntriesCount && 388691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries > 0; 389691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos j++) { 390691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos addEntry(entryViewList.get(j)); 391691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInViewGroup++; 392691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries--; 39397ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 3942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos removeView(mExpandCollapseButton); 39860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mCollapsedEntriesCount < mNumEntries 39989966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos && mExpandCollapseButton.getParent() == null && !mIsAlwaysExpanded) { 400ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos mContainer.addView(mExpandCollapseButton, -1); 4012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void addEntry(View entry) { 4051321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // If no title and the first entry in the group, add extra padding 4061321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos if (TextUtils.isEmpty(mTitleTextView.getText()) && 4071321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos mEntriesViewGroup.getChildCount() == 0) { 4081321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos entry.setPadding(entry.getPaddingLeft(), 409568d5d82610f87a5e733690e57075f0a99551972Paul Soulos getResources().getDimensionPixelSize( 410568d5d82610f87a5e733690e57075f0a99551972Paul Soulos R.dimen.expanding_entry_card_item_padding_top) + 411568d5d82610f87a5e733690e57075f0a99551972Paul Soulos getResources().getDimensionPixelSize( 4121321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_null_title_top_extra_padding), 4131321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos entry.getPaddingRight(), 4141321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos entry.getPaddingBottom()); 4151321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } 4162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup.addView(entry); 4172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 419cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos private View generateSeparator(View entry) { 4200cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos View separator = new View(getContext()); 421ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos Resources res = getResources(); 422ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos 423ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos separator.setBackgroundColor(res.getColor( 4240cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos R.color.expanding_entry_card_item_separator_color)); 425ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 426ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos ViewGroup.LayoutParams.MATCH_PARENT, 427ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_separator_height)); 4280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // The separator is aligned with the text in the entry. This is offset by a default 4290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // margin. If there is an icon present, the icon's width and margin are added 430ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos int marginStart = res.getDimensionPixelSize( 4310cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos R.dimen.expanding_entry_card_item_padding_start); 4320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ImageView entryIcon = (ImageView) entry.findViewById(R.id.icon); 43397ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (entryIcon.getVisibility() == View.VISIBLE) { 4340cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos int imageWidthAndMargin = 435ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_icon_width) + 436ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_image_spacing); 4370cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos marginStart += imageWidthAndMargin; 4380cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 43997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos layoutParams.setMarginStart(marginStart); 4400cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos separator.setLayoutParams(layoutParams); 441cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos return separator; 4420cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 4430cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 4442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence getExpandButtonText() { 4452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (!TextUtils.isEmpty(mExpandButtonText)) { 4462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mExpandButtonText; 4472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 4482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos // Default to "See more". 4492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return getResources().getText(R.string.expanding_entry_card_view_see_more); 4502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence getCollapseButtonText() { 4542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (!TextUtils.isEmpty(mCollapseButtonText)) { 4552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mCollapseButtonText; 4562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 4572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos // Default to "See less". 4582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return getResources().getText(R.string.expanding_entry_card_view_see_less); 4592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4620d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell /** 46360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos * Inflates the initial entries to be shown. 4640d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell */ 46560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private void inflateInitialEntries(LayoutInflater layoutInflater) { 46660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // If the number of collapsed entries equals total entries, inflate all 46760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mCollapsedEntriesCount == mNumEntries) { 46860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(layoutInflater); 46960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } else { 47060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // Otherwise inflate the top entry from each list 471691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // extraEntries is used to add extra entries until mCollapsedEntriesCount is reached. 472691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int numInflated = 0; 473691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int extraEntries = mCollapsedEntriesCount - mEntries.size(); 474691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int i = 0; i < mEntries.size() && numInflated < mCollapsedEntriesCount; i++) { 475691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<Entry> entryList = mEntries.get(i); 476691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<View> entryViewList = mEntryViews.get(i); 477691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos 478691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos entryViewList.add(createEntryView(layoutInflater, entryList.get(0), 47997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos /* showIcon = */ View.VISIBLE)); 480691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInflated++; 481691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // Inflate entries in this list to hit mCollapsedEntriesCount. 482691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int j = 1; j < entryList.size() && numInflated < mCollapsedEntriesCount && 483691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries > 0; j++) { 484691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos entryViewList.add(createEntryView(layoutInflater, entryList.get(j), 48543e0dead719568ed610f9f111f6e7614368445efPaul Soulos /* showIcon = */ View.INVISIBLE)); 486691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInflated++; 487691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries--; 488691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos } 48960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 49060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 49160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 49260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos 49360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos /** 49460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos * Inflates all entries. 49560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos */ 49660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private void inflateAllEntries(LayoutInflater layoutInflater) { 49760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mAllEntriesInflated) { 49860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos return; 49960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 50060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int i = 0; i < mEntries.size(); i++) { 50160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos List<Entry> entryList = mEntries.get(i); 50260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos List<View> viewList = mEntryViews.get(i); 50360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int j = viewList.size(); j < entryList.size(); j++) { 50497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos final int iconVisibility; 50597ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos final Entry entry = entryList.get(j); 50697ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos // If the entry does not have an icon, mark gone. Else if it has an icon, show 50797ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos // for the first Entry in the list only 50897ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (entry.getIcon() == null) { 50997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.GONE; 51097ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } else if (j == 0) { 51197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.VISIBLE; 51297ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } else { 51397ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.INVISIBLE; 51497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 51597ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos viewList.add(createEntryView(layoutInflater, entry, iconVisibility)); 51660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 5172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 51860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mAllEntriesInflated = true; 5192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 5217b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos public void setColorAndFilter(int color, ColorFilter colorFilter) { 5227b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mThemeColor = color; 5237b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mThemeColorFilter = colorFilter; 5247b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos applyColor(); 5257b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5267b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5276095369885edcca566a812b551886e29c7ff8039Brian Attwell public void setEntryHeaderColor(int color) { 5286095369885edcca566a812b551886e29c7ff8039Brian Attwell if (mEntries != null) { 5296095369885edcca566a812b551886e29c7ff8039Brian Attwell for (List<View> entryList : mEntryViews) { 5306095369885edcca566a812b551886e29c7ff8039Brian Attwell for (View entryView : entryList) { 5316095369885edcca566a812b551886e29c7ff8039Brian Attwell TextView header = (TextView) entryView.findViewById(R.id.header); 5326095369885edcca566a812b551886e29c7ff8039Brian Attwell if (header != null) { 5336095369885edcca566a812b551886e29c7ff8039Brian Attwell header.setTextColor(color); 5346095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5356095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5366095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5376095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5386095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5396095369885edcca566a812b551886e29c7ff8039Brian Attwell 5407b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos /** 5417b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * The ColorFilter is passed in along with the color so that a new one only needs to be created 5427b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * once for the entire activity. 5437b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 1. Title 5447b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 2. Entry icons 5457b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 3. Expand/Collapse Text 5467b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 4. Expand/Collapse Button 5477b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos */ 5487b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos public void applyColor() { 5497b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mThemeColor != 0 && mThemeColorFilter != null) { 5507b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Title 5517b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mTitleTextView != null) { 5527b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mTitleTextView.setTextColor(mThemeColor); 5537b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5547b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5557b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Entry icons 5567b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mEntries != null) { 55760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<Entry> entryList : mEntries) { 55860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (Entry entry : entryList) { 55948ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos if (entry.shouldApplyColor()) { 56048ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos Drawable icon = entry.getIcon(); 56148ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos if (icon != null) { 56248ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos icon.setColorFilter(mThemeColorFilter); 56348ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos } 56460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 565dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable alternateIcon = entry.getAlternateIcon(); 566dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos if (alternateIcon != null) { 567dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setColorFilter(mThemeColorFilter); 568dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 56948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos Drawable thirdIcon = entry.getThirdIcon(); 57048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (thirdIcon != null) { 57148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setColorFilter(mThemeColorFilter); 57248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 573eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 5747b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5757b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5767b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5777b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Expand/Collapse 5787b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseTextView.setTextColor(mThemeColor); 579c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos mExpandCollapseArrow.setColorFilter(mThemeColorFilter); 5807b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5817b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5827b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5832a4207fb39330e840436215c896cde911489e111Paul Soulos private View createEntryView(LayoutInflater layoutInflater, final Entry entry, 5842a4207fb39330e840436215c896cde911489e111Paul Soulos int iconVisibility) { 5852a4207fb39330e840436215c896cde911489e111Paul Soulos final EntryView view = (EntryView) layoutInflater.inflate( 5862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos R.layout.expanding_entry_card_item, this, false); 5872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 5882a4207fb39330e840436215c896cde911489e111Paul Soulos view.setContextMenuInfo(entry.getEntryContextMenuInfo()); 58923e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos if (!TextUtils.isEmpty(entry.getPrimaryContentDescription())) { 59023e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos view.setContentDescription(entry.getPrimaryContentDescription()); 59123e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos } 592ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos 593dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView icon = (ImageView) view.findViewById(R.id.icon); 59497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos icon.setVisibility(iconVisibility); 595eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos if (entry.getIcon() != null) { 596eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos icon.setImageDrawable(entry.getIcon()); 597eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 598dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView header = (TextView) view.findViewById(R.id.header); 59903ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getHeader())) { 6002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos header.setText(entry.getHeader()); 6012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos header.setVisibility(View.GONE); 6032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 605dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView subHeader = (TextView) view.findViewById(R.id.sub_header); 60603ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getSubHeader())) { 6072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeader.setText(entry.getSubHeader()); 6082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeader.setVisibility(View.GONE); 6102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 612dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header); 6132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getSubHeaderIcon() != null) { 6142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeaderIcon.setImageDrawable(entry.getSubHeaderIcon()); 6152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeaderIcon.setVisibility(View.GONE); 6172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 619dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView text = (TextView) view.findViewById(R.id.text); 62003ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getText())) { 6212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos text.setText(entry.getText()); 6222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos text.setVisibility(View.GONE); 6242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 626dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text); 6272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getTextIcon() != null) { 6282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos textIcon.setImageDrawable(entry.getTextIcon()); 6292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 6302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos textIcon.setVisibility(View.GONE); 6312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getIntent() != null) { 6347d22b94ce50f7a65dd89d4533f2aa3a3392e7972Paul Soulos view.setOnClickListener(mOnClickListener); 6352ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos view.setTag(new EntryTag(entry.getId(), entry.getIntent())); 6362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 638a42ef76251778161d27bc07db214b8c81720e476Paul Soulos if (entry.getIntent() == null && entry.getEntryContextMenuInfo() == null) { 639a42ef76251778161d27bc07db214b8c81720e476Paul Soulos // Remove the click effect 640a42ef76251778161d27bc07db214b8c81720e476Paul Soulos view.setBackground(null); 641a42ef76251778161d27bc07db214b8c81720e476Paul Soulos } 642a42ef76251778161d27bc07db214b8c81720e476Paul Soulos 643ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // If only the header is visible, add a top margin to match icon's top margin. 644ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // Also increase the space below the header for visual comfort. 6454b943553afdb7286b33e4bc2481431e816c57967Paul Soulos if (header.getVisibility() == View.VISIBLE && subHeader.getVisibility() == View.GONE && 6464b943553afdb7286b33e4bc2481431e816c57967Paul Soulos text.getVisibility() == View.GONE) { 6474b943553afdb7286b33e4bc2481431e816c57967Paul Soulos RelativeLayout.LayoutParams headerLayoutParams = 6484b943553afdb7286b33e4bc2481431e816c57967Paul Soulos (RelativeLayout.LayoutParams) header.getLayoutParams(); 6494b943553afdb7286b33e4bc2481431e816c57967Paul Soulos headerLayoutParams.topMargin = (int) (getResources().getDimension( 650ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos R.dimen.expanding_entry_card_item_header_only_margin_top)); 651ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos headerLayoutParams.bottomMargin += (int) (getResources().getDimension( 652ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos R.dimen.expanding_entry_card_item_header_only_margin_bottom)); 6534b943553afdb7286b33e4bc2481431e816c57967Paul Soulos header.setLayoutParams(headerLayoutParams); 6544b943553afdb7286b33e4bc2481431e816c57967Paul Soulos } 6554b943553afdb7286b33e4bc2481431e816c57967Paul Soulos 656edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos // Adjust the top padding size for entries with an invisible icon. The padding depends on 657edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos // if there is a sub header or text section 658edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos if (iconVisibility == View.INVISIBLE && 659edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos (!TextUtils.isEmpty(entry.getSubHeader()) || !TextUtils.isEmpty(entry.getText()))) { 660edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.setPaddingRelative(view.getPaddingStart(), 661edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos getResources().getDimensionPixelSize( 662edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos R.dimen.expanding_entry_card_item_no_icon_margin_top), 663edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.getPaddingEnd(), 664edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.getPaddingBottom()); 665edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos } else if (iconVisibility == View.INVISIBLE && TextUtils.isEmpty(entry.getSubHeader()) 666edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos && TextUtils.isEmpty(entry.getText())) { 667ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos view.setPaddingRelative(view.getPaddingStart(), 0, view.getPaddingEnd(), 668ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos view.getPaddingBottom()); 669ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos } 670ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos 67148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos final ImageView alternateIcon = (ImageView) view.findViewById(R.id.icon_alternate); 67248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos final ImageView thirdIcon = (ImageView) view.findViewById(R.id.third_icon); 67348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 67448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (entry.getAlternateIcon() != null && entry.getAlternateIntent() != null) { 67548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setImageDrawable(entry.getAlternateIcon()); 67648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setOnClickListener(mOnClickListener); 67748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setTag(new EntryTag(entry.getId(), entry.getAlternateIntent())); 67848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setVisibility(View.VISIBLE); 67948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos alternateIcon.setContentDescription(entry.getAlternateContentDescription()); 68048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 68148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 68248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (entry.getThirdIcon() != null && entry.getThirdIntent() != null) { 68348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setImageDrawable(entry.getThirdIcon()); 68448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setOnClickListener(mOnClickListener); 68548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setTag(new EntryTag(entry.getId(), entry.getThirdIntent())); 68648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setVisibility(View.VISIBLE); 68748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos thirdIcon.setContentDescription(entry.getThirdContentDescription()); 68848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 68948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 69048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos // Set a custom touch listener for expanding the extra icon touch areas 69148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos view.setOnTouchListener(new EntryTouchListener(view, alternateIcon, thirdIcon)); 6922a4207fb39330e840436215c896cde911489e111Paul Soulos view.setOnCreateContextMenuListener(mOnCreateContextMenuListener); 6932a4207fb39330e840436215c896cde911489e111Paul Soulos 6942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return view; 6952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 697c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos private void updateExpandCollapseButton(CharSequence buttonText, long duration) { 698c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos if (mIsExpanded) { 699c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos final ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandCollapseArrow, 700c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos "rotation", 180); 701c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.setDuration(duration); 702c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.start(); 7032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 704c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos final ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandCollapseArrow, 705c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos "rotation", 0); 706c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.setDuration(duration); 707c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.start(); 7082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 709c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateBadges(); 710c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos 7112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(buttonText); 7122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7146b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private void updateBadges() { 7156b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (mIsExpanded) { 7166b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.removeAllViews(); 7176b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } else { 7186b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos // Inflate badges if not yet created 7196b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (mBadges.size() < mEntries.size() - mCollapsedEntriesCount) { 7206b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos for (int i = mCollapsedEntriesCount; i < mEntries.size(); i++) { 7216b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos Drawable badgeDrawable = mEntries.get(i).get(0).getIcon(); 72248290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos int badgeResourceId = mEntries.get(i).get(0).getIconResourceId(); 72348290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos // Do not add the same badge twice 72448290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos if (badgeResourceId != 0 && mBadgeIds.contains(badgeResourceId)) { 72548290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos continue; 72648290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos } 7276b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (badgeDrawable != null) { 7286b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos ImageView badgeView = new ImageView(getContext()); 7296b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos LinearLayout.LayoutParams badgeViewParams = new LinearLayout.LayoutParams( 7306b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos (int) getResources().getDimension( 7316b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_item_icon_width), 7326b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos (int) getResources().getDimension( 7336b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_item_icon_height)); 7346b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeViewParams.setMarginEnd((int) getResources().getDimension( 7356b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_badge_separator_margin)); 7366b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeView.setLayoutParams(badgeViewParams); 7376b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeView.setImageDrawable(badgeDrawable); 7386b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadges.add(badgeView); 73948290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos mBadgeIds.add(badgeResourceId); 7406b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7416b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7426b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7436b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.removeAllViews(); 7446b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos for (ImageView badge : mBadges) { 7456b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.addView(badge); 7466b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7476b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7486b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7496b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos 7502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void expand() { 7510cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ChangeBounds boundsTransition = new ChangeBounds(); 7520cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.setDuration(DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS); 7530cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7540cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos Fade fadeIn = new Fade(Fade.IN); 7550cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos fadeIn.setDuration(DURATION_EXPAND_ANIMATION_FADE_IN); 7560cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos fadeIn.setStartDelay(DELAY_EXPAND_ANIMATION_FADE_IN); 7570cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7580cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionSet transitionSet = new TransitionSet(); 7590cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(boundsTransition); 7600cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(fadeIn); 7610cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7624cd9ed68dca5f4adeb8ec2065526c18f33af5926Paul Soulos transitionSet.excludeTarget(R.id.text, /* exclude = */ true); 7634cd9ed68dca5f4adeb8ec2065526c18f33af5926Paul Soulos 7640cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ViewGroup transitionViewContainer = mAnimationViewGroup == null ? 7650cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos this : mAnimationViewGroup; 7660cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7670cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addListener(new TransitionListener() { 7680cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7690cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionStart(Transition transition) { 7700cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // The listener is used to turn off suppressing, the proper delta is not necessary 7710cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mListener.onExpand(0); 7720cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7730cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7740cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7750cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionEnd(Transition transition) { 7760cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7770cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7780cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7790cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionCancel(Transition transition) { 7800cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7810cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7820cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7830cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionPause(Transition transition) { 7840cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7850cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7860cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7870cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionResume(Transition transition) { 7880cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7890cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos }); 7900cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7910cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet); 7922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = true; 7940d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell // In order to insert new entries, we may need to inflate them for the first time 79560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(LayoutInflater.from(getContext())); 7962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos insertEntriesIntoViewGroup(); 797c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getCollapseButtonText(), 798c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS); 7992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void collapse() { 8020cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final int startingHeight = mEntriesViewGroup.getMeasuredHeight(); 8032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = false; 804c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getExpandButtonText(), 805c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 8062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8070cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ChangeBounds boundsTransition = new ChangeBounds(); 8080cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 8092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8100cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ChangeScroll scrollTransition = new ChangeScroll(); 8110cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos scrollTransition.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 8120cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8130cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionSet transitionSet = new TransitionSet(); 8140cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(boundsTransition); 8150cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(scrollTransition); 8160cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 817c23508e6e4740d798147f15c8ce1dff3395079bdPaul Soulos transitionSet.excludeTarget(R.id.text, /* exclude = */ true); 818c23508e6e4740d798147f15c8ce1dff3395079bdPaul Soulos 8190cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ViewGroup transitionViewContainer = mAnimationViewGroup == null ? 8200cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos this : mAnimationViewGroup; 8210cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8220cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.addListener(new TransitionListener() { 8232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 8240cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionStart(Transition transition) { 8250cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos /* 8260cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos * onTransitionStart is called after the view hierarchy has been changed but before 8270cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos * the animation begins. 8280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos */ 8290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos int finishingHeight = mEntriesViewGroup.getMeasuredHeight(); 8300cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mListener.onCollapse(startingHeight - finishingHeight); 8312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8330cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8340cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionEnd(Transition transition) { 8350cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8360cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 8380cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionCancel(Transition transition) { 8390cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8400cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8410cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8420cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionPause(Transition transition) { 8430cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8440cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8450cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8460cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionResume(Transition transition) { 8472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos }); 8490cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8500cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet); 8510cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8520cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos insertEntriesIntoViewGroup(); 8532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 8562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Returns whether the view is currently in its expanded state. 8572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 8582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public boolean isExpanded() { 8592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIsExpanded; 8602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 8632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the title text of this ExpandingEntryCardView. 8642fa690807a94708384789b211965bfc75b5ac38ePaul Soulos * @param title The title to set. A null title will result in the title being removed. 8652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 8662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setTitle(String title) { 8672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mTitleTextView == null) { 8682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Log.e(TAG, "mTitleTextView is null"); 8692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTitleTextView.setText(title); 8711321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos mTitleTextView.setVisibility(TextUtils.isEmpty(title) ? View.GONE : View.VISIBLE); 8721321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos findViewById(R.id.title_separator).setVisibility(TextUtils.isEmpty(title) ? 8731321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View.GONE : View.VISIBLE); 8741321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // If the title is set after children have been added, reset the top entry's padding to 8751321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // the default. Else if the title is cleared after children have been added, set 8761321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // the extra top padding 8771321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos if (!TextUtils.isEmpty(title) && mEntriesViewGroup.getChildCount() > 0) { 8781321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View firstEntry = mEntriesViewGroup.getChildAt(0); 8791321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.setPadding(firstEntry.getPaddingLeft(), 8801321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 8811321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_item_padding_top), 8821321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingRight(), 8831321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingBottom()); 8841321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } else if (!TextUtils.isEmpty(title) && mEntriesViewGroup.getChildCount() > 0) { 8851321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View firstEntry = mEntriesViewGroup.getChildAt(0); 8861321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.setPadding(firstEntry.getPaddingLeft(), 8871321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 8881321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_item_padding_top) + 8891321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 8901321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_null_title_top_extra_padding), 8911321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingRight(), 8921321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingBottom()); 8931321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } 8942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 895eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos 896eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos public boolean shouldShow() { 897eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos return mEntries != null && mEntries.size() > 0; 898eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 8992a4207fb39330e840436215c896cde911489e111Paul Soulos 9002a4207fb39330e840436215c896cde911489e111Paul Soulos public static final class EntryView extends RelativeLayout { 9012a4207fb39330e840436215c896cde911489e111Paul Soulos private EntryContextMenuInfo mEntryContextMenuInfo; 9022a4207fb39330e840436215c896cde911489e111Paul Soulos 9032a4207fb39330e840436215c896cde911489e111Paul Soulos public EntryView(Context context) { 9042a4207fb39330e840436215c896cde911489e111Paul Soulos super(context); 9052a4207fb39330e840436215c896cde911489e111Paul Soulos } 9062a4207fb39330e840436215c896cde911489e111Paul Soulos 9072a4207fb39330e840436215c896cde911489e111Paul Soulos public EntryView(Context context, AttributeSet attrs) { 9082a4207fb39330e840436215c896cde911489e111Paul Soulos super(context, attrs); 9092a4207fb39330e840436215c896cde911489e111Paul Soulos } 9102a4207fb39330e840436215c896cde911489e111Paul Soulos 9112a4207fb39330e840436215c896cde911489e111Paul Soulos public void setContextMenuInfo(EntryContextMenuInfo info) { 9122a4207fb39330e840436215c896cde911489e111Paul Soulos mEntryContextMenuInfo = info; 9132a4207fb39330e840436215c896cde911489e111Paul Soulos } 9142a4207fb39330e840436215c896cde911489e111Paul Soulos 9152a4207fb39330e840436215c896cde911489e111Paul Soulos @Override 9162a4207fb39330e840436215c896cde911489e111Paul Soulos protected ContextMenuInfo getContextMenuInfo() { 9172a4207fb39330e840436215c896cde911489e111Paul Soulos return mEntryContextMenuInfo; 9182a4207fb39330e840436215c896cde911489e111Paul Soulos } 9192a4207fb39330e840436215c896cde911489e111Paul Soulos } 9202a4207fb39330e840436215c896cde911489e111Paul Soulos 9212a4207fb39330e840436215c896cde911489e111Paul Soulos public static final class EntryContextMenuInfo implements ContextMenuInfo { 9222a4207fb39330e840436215c896cde911489e111Paul Soulos private final String mCopyText; 9232a4207fb39330e840436215c896cde911489e111Paul Soulos private final String mCopyLabel; 92497f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos private final String mMimeType; 92597f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos private final long mId; 92697f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos private final boolean mIsSuperPrimary; 9272a4207fb39330e840436215c896cde911489e111Paul Soulos 92897f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos public EntryContextMenuInfo(String copyText, String copyLabel, String mimeType, long id, 92997f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos boolean isSuperPrimary) { 9302a4207fb39330e840436215c896cde911489e111Paul Soulos mCopyText = copyText; 9312a4207fb39330e840436215c896cde911489e111Paul Soulos mCopyLabel = copyLabel; 93297f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos mMimeType = mimeType; 93397f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos mId = id; 93497f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos mIsSuperPrimary = isSuperPrimary; 9352a4207fb39330e840436215c896cde911489e111Paul Soulos } 9362a4207fb39330e840436215c896cde911489e111Paul Soulos 9372a4207fb39330e840436215c896cde911489e111Paul Soulos public String getCopyText() { 9382a4207fb39330e840436215c896cde911489e111Paul Soulos return mCopyText; 9392a4207fb39330e840436215c896cde911489e111Paul Soulos } 9402a4207fb39330e840436215c896cde911489e111Paul Soulos 9412a4207fb39330e840436215c896cde911489e111Paul Soulos public String getCopyLabel() { 9422a4207fb39330e840436215c896cde911489e111Paul Soulos return mCopyLabel; 9432a4207fb39330e840436215c896cde911489e111Paul Soulos } 94497f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos 94597f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos public String getMimeType() { 94697f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos return mMimeType; 94797f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos } 94897f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos 94997f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos public long getId() { 95097f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos return mId; 95197f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos } 95297f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos 95397f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos public boolean isSuperPrimary() { 95497f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos return mIsSuperPrimary; 95597f27809c3e6153ce0bc5050bc5ee466a646e8ecPaul Soulos } 9562a4207fb39330e840436215c896cde911489e111Paul Soulos } 9572ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9582ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos static final class EntryTag { 9592ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos private final int mId; 9602ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos private final Intent mIntent; 9612ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9622ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public EntryTag(int id, Intent intent) { 9632ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mId = id; 9642ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mIntent = intent; 9652ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 9662ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9672ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public int getId() { 9682ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mId; 9692ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 9702ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9712ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public Intent getIntent() { 9722ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mIntent; 9732ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 9742ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 97548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 97648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos /** 97748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos * This custom touch listener increases the touch area for the second and third icons, if 97848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos * they are present. This is necessary to maintain other properties on an entry view, like 97948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos * using a top padding on entry. Based off of {@link android.view.TouchDelegate} 98048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos */ 98148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private static final class EntryTouchListener implements View.OnTouchListener { 98248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final View mEntry; 98348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final ImageView mAlternateIcon; 98448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private final ImageView mThirdIcon; 98548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos /** mTouchedView locks in a view on touch down */ 98648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private View mTouchedView; 98748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos /** mSlop adds some space to account for touches that are just outside the hit area */ 98848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private int mSlop; 98948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 99048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos public EntryTouchListener(View entry, ImageView alternateIcon, ImageView thirdIcon) { 99148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mEntry = entry; 99248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mAlternateIcon = alternateIcon; 99348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mThirdIcon = thirdIcon; 99448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mSlop = ViewConfiguration.get(entry.getContext()).getScaledTouchSlop(); 99548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 99648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 99748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos @Override 99848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos public boolean onTouch(View v, MotionEvent event) { 99948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos View touchedView = mTouchedView; 100048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos boolean sendToTouched = false; 100148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos boolean hit = true; 100248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos boolean handled = false; 100348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 100448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos switch (event.getAction()) { 100548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos case MotionEvent.ACTION_DOWN: 100648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (hitThirdIcon(event)) { 100748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mTouchedView = mThirdIcon; 100848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = true; 100948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else if (hitAlternateIcon(event)) { 101048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mTouchedView = mAlternateIcon; 101148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = true; 101248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else { 101348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mTouchedView = mEntry; 101448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = false; 101548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 101648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos touchedView = mTouchedView; 101748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos break; 101848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos case MotionEvent.ACTION_UP: 101948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos case MotionEvent.ACTION_MOVE: 102048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = mTouchedView != null && mTouchedView != mEntry; 102148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (sendToTouched) { 102248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos final Rect slopBounds = new Rect(); 102348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos touchedView.getHitRect(slopBounds); 102448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos slopBounds.inset(-mSlop, -mSlop); 102548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (!slopBounds.contains((int) event.getX(), (int) event.getY())) { 102648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos hit = false; 102748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 102848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 102948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos break; 103048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos case MotionEvent.ACTION_CANCEL: 103148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos sendToTouched = mTouchedView != null && mTouchedView != mEntry; 103248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos mTouchedView = null; 103348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos break; 103448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 103548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (sendToTouched) { 103648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (hit) { 103748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.setLocation(touchedView.getWidth() / 2, touchedView.getHeight() / 2); 103848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else { 103948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos // Offset event coordinates to be outside the target view (in case it does 104048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos // something like tracking pressed state) 104148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.setLocation(-(mSlop * 2), -(mSlop * 2)); 104248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 104348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos handled = touchedView.dispatchTouchEvent(event); 104448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 104548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return handled; 104648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 104748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 104848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private boolean hitThirdIcon(MotionEvent event) { 104948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (mEntry.isLayoutRtl()) { 105048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdIcon.getVisibility() == View.VISIBLE && 105148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.getX() < mThirdIcon.getRight(); 105248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else { 105348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mThirdIcon.getVisibility() == View.VISIBLE && 105448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.getX() > mThirdIcon.getLeft(); 105548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 105648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 105748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos 105848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos /** 105948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos * Should be used after checking if third icon was hit 106048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos */ 106148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos private boolean hitAlternateIcon(MotionEvent event) { 106248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos // LayoutParams used to add the start margin to the touch area 106348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos final RelativeLayout.LayoutParams alternateIconParams = 106448fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos (RelativeLayout.LayoutParams) mAlternateIcon.getLayoutParams(); 106548fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos if (mEntry.isLayoutRtl()) { 106648fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mAlternateIcon.getVisibility() == View.VISIBLE && 106748fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.getX() < mAlternateIcon.getRight() + alternateIconParams.rightMargin; 106848fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } else { 106948fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos return mAlternateIcon.getVisibility() == View.VISIBLE && 107048fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos event.getX() > mAlternateIcon.getLeft() - alternateIconParams.leftMargin; 107148fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 107248fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 107348fc91217042fd854f0e96c2028c188e50a5e21dPaul Soulos } 10742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos} 1075