ExpandingEntryCardView.java revision cc5ec22992ee61d130cb2ee99a038fb1761b8d35
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; 262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.text.TextUtils; 270cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.ChangeBounds; 280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.ChangeScroll; 290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Fade; 300cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Transition; 310cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Transition.TransitionListener; 320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.TransitionManager; 330cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.TransitionSet; 342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.AttributeSet; 352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.Log; 362a4207fb39330e840436215c896cde911489e111Paul Soulosimport android.view.ContextMenu.ContextMenuInfo; 372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.LayoutInflater; 38dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulosimport android.view.TouchDelegate; 392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.View; 402a4207fb39330e840436215c896cde911489e111Paul Soulosimport android.view.View.OnCreateContextMenuListener; 412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.ViewGroup; 42ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulosimport android.widget.FrameLayout; 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; 772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Intent mIntent; 78dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final Drawable mAlternateIcon; 79dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final Intent mAlternateIntent; 80dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final String mAlternateContentDescription; 8148ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos private final boolean mShouldApplyColor; 822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final boolean mIsEditable; 832a4207fb39330e840436215c896cde911489e111Paul Soulos private final EntryContextMenuInfo mEntryContextMenuInfo; 842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 852ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public Entry(int id, Drawable icon, String header, String subHeader, String text, 86dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Intent intent, Drawable alternateIcon, Intent alternateIntent, 87dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos String alternateContentDescription, boolean shouldApplyColor, 882a4207fb39330e840436215c896cde911489e111Paul Soulos boolean isEditable, EntryContextMenuInfo entryContextMenuInfo) { 892ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos this(id, icon, header, subHeader, null, text, null, intent, alternateIcon, 902a4207fb39330e840436215c896cde911489e111Paul Soulos alternateIntent, alternateContentDescription, shouldApplyColor, isEditable, 912a4207fb39330e840436215c896cde911489e111Paul Soulos entryContextMenuInfo); 922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 942ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public Entry(int id, Drawable mainIcon, String header, String subHeader, 952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable subHeaderIcon, String text, Drawable textIcon, Intent intent, 96dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable alternateIcon, Intent alternateIntent, String alternateContentDescription, 972a4207fb39330e840436215c896cde911489e111Paul Soulos boolean shouldApplyColor, boolean isEditable, 982a4207fb39330e840436215c896cde911489e111Paul Soulos EntryContextMenuInfo entryContextMenuInfo) { 992ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mId = id; 1002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIcon = mainIcon; 1012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mHeader = header; 1022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mSubHeader = subHeader; 1032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mSubHeaderIcon = subHeaderIcon; 1042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mText = text; 1052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTextIcon = textIcon; 1062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIntent = intent; 107dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateIcon = alternateIcon; 108dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateIntent = alternateIntent; 109dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateContentDescription = alternateContentDescription; 11048ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos mShouldApplyColor = shouldApplyColor; 1112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsEditable = isEditable; 1122a4207fb39330e840436215c896cde911489e111Paul Soulos mEntryContextMenuInfo = entryContextMenuInfo; 1132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getIcon() { 1162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIcon; 1172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos String getHeader() { 1202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mHeader; 1212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos String getSubHeader() { 1242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mSubHeader; 1252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getSubHeaderIcon() { 1282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mSubHeaderIcon; 1292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public String getText() { 1322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mText; 1332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getTextIcon() { 1362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mTextIcon; 1372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Intent getIntent() { 1402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIntent; 1412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 143dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable getAlternateIcon() { 144dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateIcon; 145dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 146dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 147dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Intent getAlternateIntent() { 148dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateIntent; 149dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 150dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 151dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos String getAlternateContentDescription() { 152dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateContentDescription; 153dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 154dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 15548ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos boolean shouldApplyColor() { 15648ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos return mShouldApplyColor; 15748ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos } 15848ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos 1592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos boolean isEditable() { 1602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIsEditable; 1612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 162ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos 1632ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos int getId() { 1642ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mId; 165ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos } 1662a4207fb39330e840436215c896cde911489e111Paul Soulos 1672a4207fb39330e840436215c896cde911489e111Paul Soulos EntryContextMenuInfo getEntryContextMenuInfo() { 1682a4207fb39330e840436215c896cde911489e111Paul Soulos return mEntryContextMenuInfo; 1692a4207fb39330e840436215c896cde911489e111Paul Soulos } 1702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 172e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell public interface ExpandingEntryCardViewListener { 173e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell void onCollapse(int heightDelta); 1740cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos void onExpand(int heightDelta); 175e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell } 176e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell 1772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private View mExpandCollapseButton; 1782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private TextView mExpandCollapseTextView; 1792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private TextView mTitleTextView; 1802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence mExpandButtonText; 1812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence mCollapseButtonText; 1822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private OnClickListener mOnClickListener; 1832a4207fb39330e840436215c896cde911489e111Paul Soulos private OnCreateContextMenuListener mOnCreateContextMenuListener; 1842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private boolean mIsExpanded = false; 185691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos /** 186691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos * The max number of entries to show in a collapsed card. If there are less entries passed in, 187691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos * then they are all shown. 188691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos */ 1892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private int mCollapsedEntriesCount; 190e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell private ExpandingEntryCardViewListener mListener; 19160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private List<List<Entry>> mEntries; 19260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private int mNumEntries = 0; 19360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private boolean mAllEntriesInflated = false; 19460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private List<List<View>> mEntryViews; 1952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private LinearLayout mEntriesViewGroup; 196c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos private final ImageView mExpandCollapseArrow; 1972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private int mThemeColor; 1987b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos private ColorFilter mThemeColorFilter; 19989966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos private boolean mIsAlwaysExpanded; 2000cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos /** The ViewGroup to run the expand/collapse animation on */ 2010cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private ViewGroup mAnimationViewGroup; 2026b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private LinearLayout mBadgeContainer; 2036b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private final List<ImageView> mBadges; 204cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos /** 205cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos * List to hold the separators. This saves us from reconstructing every expand/collapse and 206cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos * provides a smoother animation. 207cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos */ 208cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos private List<View> mSeparators; 209ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos private LinearLayout mContainer; 2102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final OnClickListener mExpandCollapseButtonListener = new OnClickListener() { 2122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 2132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void onClick(View v) { 2142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mIsExpanded) { 2152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos collapse(); 2162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 2172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos expand(); 2182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos }; 2212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public ExpandingEntryCardView(Context context) { 2230d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell this(context, null); 2242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public ExpandingEntryCardView(Context context, AttributeSet attrs) { 2272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos super(context, attrs); 2282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos LayoutInflater inflater = LayoutInflater.from(context); 2292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos View expandingEntryCardView = inflater.inflate(R.layout.expanding_entry_card_view, this); 2302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup = (LinearLayout) 2312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos expandingEntryCardView.findViewById(R.id.content_area_linear_layout); 2322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTitleTextView = (TextView) expandingEntryCardView.findViewById(R.id.title); 233ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos mContainer = (LinearLayout) expandingEntryCardView.findViewById(R.id.container); 2347b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 2357b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseButton = inflater.inflate( 2367b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos R.layout.quickcontact_expanding_entry_card_button, this, false); 2377b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseTextView = (TextView) mExpandCollapseButton.findViewById(R.id.text); 238c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos mExpandCollapseArrow = (ImageView) mExpandCollapseButton.findViewById(R.id.arrow); 2397b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseButton.setOnClickListener(mExpandCollapseButtonListener); 2406b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer = (LinearLayout) mExpandCollapseButton.findViewById(R.id.badge_container); 2417b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 2426b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadges = new ArrayList<ImageView>(); 2432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 2462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the Entry list to display. 2472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 2482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param entries The Entry list to display. 2492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 25060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos public void initialize(List<List<Entry>> entries, int numInitialVisibleEntries, 25189966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos boolean isExpanded, boolean isAlwaysExpanded, 2520cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ExpandingEntryCardViewListener listener, ViewGroup animationViewGroup) { 2532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos LayoutInflater layoutInflater = LayoutInflater.from(getContext()); 2542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = isExpanded; 25589966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos mIsAlwaysExpanded = isAlwaysExpanded; 25689966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos // If isAlwaysExpanded is true, mIsExpanded should be true 25789966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos mIsExpanded |= mIsAlwaysExpanded; 25860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mEntryViews = new ArrayList<List<View>>(entries.size()); 2590d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell mEntries = entries; 2606095369885edcca566a812b551886e29c7ff8039Brian Attwell mNumEntries = 0; 2616095369885edcca566a812b551886e29c7ff8039Brian Attwell mAllEntriesInflated = false; 26260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<Entry> entryList : mEntries) { 26360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mNumEntries += entryList.size(); 26460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mEntryViews.add(new ArrayList<View>()); 26560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 26660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mCollapsedEntriesCount = Math.min(numInitialVisibleEntries, mNumEntries); 267cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos // We need a separator between each list, but not after the last one 268cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (entries.size() > 1) { 269cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators = new ArrayList<>(entries.size() - 1); 270cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 271e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell mListener = listener; 2720cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mAnimationViewGroup = animationViewGroup; 2730d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell 2747b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mIsExpanded) { 275c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getCollapseButtonText(), /* duration = */ 0); 27660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(layoutInflater); 2777b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } else { 278c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getExpandButtonText(), /* duration = */ 0); 27960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateInitialEntries(layoutInflater); 2802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos insertEntriesIntoViewGroup(); 2827b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos applyColor(); 2832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 2862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the text for the expand button. 2872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 2882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param expandButtonText The expand button text. 2892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 2902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setExpandButtonText(CharSequence expandButtonText) { 2912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandButtonText = expandButtonText; 2922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mExpandCollapseTextView != null && !mIsExpanded) { 2932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(expandButtonText); 2942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 2982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the text for the expand button. 2992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 3002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param expandButtonText The expand button text. 3012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 3022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setCollapseButtonText(CharSequence expandButtonText) { 3032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mCollapseButtonText = expandButtonText; 3042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mExpandCollapseTextView != null && mIsExpanded) { 3052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(mCollapseButtonText); 3062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 3102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setOnClickListener(OnClickListener listener) { 3112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mOnClickListener = listener; 3122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3142a4207fb39330e840436215c896cde911489e111Paul Soulos @Override 3152a4207fb39330e840436215c896cde911489e111Paul Soulos public void setOnCreateContextMenuListener (OnCreateContextMenuListener listener) { 3162a4207fb39330e840436215c896cde911489e111Paul Soulos mOnCreateContextMenuListener = listener; 3172a4207fb39330e840436215c896cde911489e111Paul Soulos } 3182a4207fb39330e840436215c896cde911489e111Paul Soulos 3192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void insertEntriesIntoViewGroup() { 3202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup.removeAllViews(); 32160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos 3222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mIsExpanded) { 323cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos for (int i = 0; i < mEntryViews.size(); i++) { 324cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos List<View> viewList = mEntryViews.get(i); 325cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (i > 0) { 326cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos View separator; 327cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (mSeparators.size() <= i - 1) { 328cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = generateSeparator(viewList.get(0)); 329cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators.add(separator); 330cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } else { 331cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = mSeparators.get(i - 1); 332cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 333cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mEntriesViewGroup.addView(separator); 33497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 33560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (View view : viewList) { 33660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos addEntry(view); 33760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 33860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 33960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } else { 340691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // We want to insert mCollapsedEntriesCount entries into the group. extraEntries is the 341691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // number of entries that need to be added that are not the head element of a list 342691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // to reach mCollapsedEntriesCount. 343691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int numInViewGroup = 0; 344691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int extraEntries = mCollapsedEntriesCount - mEntryViews.size(); 345691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int i = 0; i < mEntryViews.size() && numInViewGroup < mCollapsedEntriesCount; 346691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos i++) { 347691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<View> entryViewList = mEntryViews.get(i); 34897ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (i > 0) { 349cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos View separator; 350cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos if (mSeparators.size() <= i - 1) { 351cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = generateSeparator(entryViewList.get(0)); 352cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mSeparators.add(separator); 353cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } else { 354cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos separator = mSeparators.get(i - 1); 355cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos } 356cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos mEntriesViewGroup.addView(separator); 357691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos } 358691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos addEntry(entryViewList.get(0)); 359691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInViewGroup++; 360691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // Insert entries in this list to hit mCollapsedEntriesCount. 361691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int j = 1; 362691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos j < entryViewList.size() && numInViewGroup < mCollapsedEntriesCount && 363691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries > 0; 364691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos j++) { 365691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos addEntry(entryViewList.get(j)); 366691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInViewGroup++; 367691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries--; 36897ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 3692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos removeView(mExpandCollapseButton); 37360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mCollapsedEntriesCount < mNumEntries 37489966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos && mExpandCollapseButton.getParent() == null && !mIsAlwaysExpanded) { 375ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos mContainer.addView(mExpandCollapseButton, -1); 3762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void addEntry(View entry) { 3801321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // If no title and the first entry in the group, add extra padding 3811321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos if (TextUtils.isEmpty(mTitleTextView.getText()) && 3821321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos mEntriesViewGroup.getChildCount() == 0) { 3831321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos entry.setPadding(entry.getPaddingLeft(), 384568d5d82610f87a5e733690e57075f0a99551972Paul Soulos getResources().getDimensionPixelSize( 385568d5d82610f87a5e733690e57075f0a99551972Paul Soulos R.dimen.expanding_entry_card_item_padding_top) + 386568d5d82610f87a5e733690e57075f0a99551972Paul Soulos getResources().getDimensionPixelSize( 3871321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_null_title_top_extra_padding), 3881321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos entry.getPaddingRight(), 3891321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos entry.getPaddingBottom()); 3901321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } 3912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup.addView(entry); 3922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 394cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos private View generateSeparator(View entry) { 3950cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos View separator = new View(getContext()); 396ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos Resources res = getResources(); 397ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos 398ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos separator.setBackgroundColor(res.getColor( 3990cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos R.color.expanding_entry_card_item_separator_color)); 400ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 401ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos ViewGroup.LayoutParams.MATCH_PARENT, 402ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_separator_height)); 4030cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // The separator is aligned with the text in the entry. This is offset by a default 4040cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // margin. If there is an icon present, the icon's width and margin are added 405ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos int marginStart = res.getDimensionPixelSize( 4060cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos R.dimen.expanding_entry_card_item_padding_start); 4070cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ImageView entryIcon = (ImageView) entry.findViewById(R.id.icon); 40897ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (entryIcon.getVisibility() == View.VISIBLE) { 4090cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos int imageWidthAndMargin = 410ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_icon_width) + 411ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_image_spacing); 4120cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos marginStart += imageWidthAndMargin; 4130cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 41497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos layoutParams.setMarginStart(marginStart); 4150cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos separator.setLayoutParams(layoutParams); 416cc5ec22992ee61d130cb2ee99a038fb1761b8d35Paul Soulos return separator; 4170cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 4180cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 4192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence getExpandButtonText() { 4202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (!TextUtils.isEmpty(mExpandButtonText)) { 4212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mExpandButtonText; 4222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 4232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos // Default to "See more". 4242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return getResources().getText(R.string.expanding_entry_card_view_see_more); 4252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence getCollapseButtonText() { 4292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (!TextUtils.isEmpty(mCollapseButtonText)) { 4302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mCollapseButtonText; 4312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 4322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos // Default to "See less". 4332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return getResources().getText(R.string.expanding_entry_card_view_see_less); 4342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4370d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell /** 43860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos * Inflates the initial entries to be shown. 4390d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell */ 44060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private void inflateInitialEntries(LayoutInflater layoutInflater) { 44160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // If the number of collapsed entries equals total entries, inflate all 44260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mCollapsedEntriesCount == mNumEntries) { 44360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(layoutInflater); 44460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } else { 44560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // Otherwise inflate the top entry from each list 446691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // extraEntries is used to add extra entries until mCollapsedEntriesCount is reached. 447691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int numInflated = 0; 448691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos int extraEntries = mCollapsedEntriesCount - mEntries.size(); 449691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int i = 0; i < mEntries.size() && numInflated < mCollapsedEntriesCount; i++) { 450691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<Entry> entryList = mEntries.get(i); 451691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos List<View> entryViewList = mEntryViews.get(i); 452691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos 453691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos entryViewList.add(createEntryView(layoutInflater, entryList.get(0), 45497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos /* showIcon = */ View.VISIBLE)); 455691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInflated++; 456691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos // Inflate entries in this list to hit mCollapsedEntriesCount. 457691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos for (int j = 1; j < entryList.size() && numInflated < mCollapsedEntriesCount && 458691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries > 0; j++) { 459691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos entryViewList.add(createEntryView(layoutInflater, entryList.get(j), 46043e0dead719568ed610f9f111f6e7614368445efPaul Soulos /* showIcon = */ View.INVISIBLE)); 461691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos numInflated++; 462691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos extraEntries--; 463691dd8fc7ce4b330cb6341f8e54fa6703564bd3ePaul Soulos } 46460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 46560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 46660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 46760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos 46860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos /** 46960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos * Inflates all entries. 47060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos */ 47160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private void inflateAllEntries(LayoutInflater layoutInflater) { 47260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mAllEntriesInflated) { 47360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos return; 47460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 47560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int i = 0; i < mEntries.size(); i++) { 47660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos List<Entry> entryList = mEntries.get(i); 47760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos List<View> viewList = mEntryViews.get(i); 47860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int j = viewList.size(); j < entryList.size(); j++) { 47997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos final int iconVisibility; 48097ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos final Entry entry = entryList.get(j); 48197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos // If the entry does not have an icon, mark gone. Else if it has an icon, show 48297ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos // for the first Entry in the list only 48397ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (entry.getIcon() == null) { 48497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.GONE; 48597ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } else if (j == 0) { 48697ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.VISIBLE; 48797ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } else { 48897ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.INVISIBLE; 48997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 49097ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos viewList.add(createEntryView(layoutInflater, entry, iconVisibility)); 49160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 4922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 49360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mAllEntriesInflated = true; 4942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4967b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos public void setColorAndFilter(int color, ColorFilter colorFilter) { 4977b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mThemeColor = color; 4987b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mThemeColorFilter = colorFilter; 4997b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos applyColor(); 5007b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5017b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5026095369885edcca566a812b551886e29c7ff8039Brian Attwell public void setEntryHeaderColor(int color) { 5036095369885edcca566a812b551886e29c7ff8039Brian Attwell if (mEntries != null) { 5046095369885edcca566a812b551886e29c7ff8039Brian Attwell for (List<View> entryList : mEntryViews) { 5056095369885edcca566a812b551886e29c7ff8039Brian Attwell for (View entryView : entryList) { 5066095369885edcca566a812b551886e29c7ff8039Brian Attwell TextView header = (TextView) entryView.findViewById(R.id.header); 5076095369885edcca566a812b551886e29c7ff8039Brian Attwell if (header != null) { 5086095369885edcca566a812b551886e29c7ff8039Brian Attwell header.setTextColor(color); 5096095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5106095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5116095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5126095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5136095369885edcca566a812b551886e29c7ff8039Brian Attwell } 5146095369885edcca566a812b551886e29c7ff8039Brian Attwell 5157b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos /** 5167b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * The ColorFilter is passed in along with the color so that a new one only needs to be created 5177b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * once for the entire activity. 5187b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 1. Title 5197b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 2. Entry icons 5207b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 3. Expand/Collapse Text 5217b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 4. Expand/Collapse Button 5227b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos */ 5237b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos public void applyColor() { 5247b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mThemeColor != 0 && mThemeColorFilter != null) { 5257b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Title 5267b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mTitleTextView != null) { 5277b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mTitleTextView.setTextColor(mThemeColor); 5287b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5297b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5307b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Entry icons 5317b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mEntries != null) { 53260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<Entry> entryList : mEntries) { 53360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (Entry entry : entryList) { 53448ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos if (entry.shouldApplyColor()) { 53548ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos Drawable icon = entry.getIcon(); 53648ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos if (icon != null) { 53748ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos icon.setColorFilter(mThemeColorFilter); 53848ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos } 53960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 540dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable alternateIcon = entry.getAlternateIcon(); 541dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos if (alternateIcon != null) { 542dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setColorFilter(mThemeColorFilter); 543dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 544eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 5457b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5467b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5477b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5487b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Expand/Collapse 5497b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseTextView.setTextColor(mThemeColor); 550c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos mExpandCollapseArrow.setColorFilter(mThemeColorFilter); 5517b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5527b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 5537b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 5542a4207fb39330e840436215c896cde911489e111Paul Soulos private View createEntryView(LayoutInflater layoutInflater, final Entry entry, 5552a4207fb39330e840436215c896cde911489e111Paul Soulos int iconVisibility) { 5562a4207fb39330e840436215c896cde911489e111Paul Soulos final EntryView view = (EntryView) layoutInflater.inflate( 5572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos R.layout.expanding_entry_card_item, this, false); 5582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 5592a4207fb39330e840436215c896cde911489e111Paul Soulos view.setContextMenuInfo(entry.getEntryContextMenuInfo()); 560ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos 561dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView icon = (ImageView) view.findViewById(R.id.icon); 56297ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos icon.setVisibility(iconVisibility); 563eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos if (entry.getIcon() != null) { 564eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos icon.setImageDrawable(entry.getIcon()); 565eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 566dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView header = (TextView) view.findViewById(R.id.header); 56703ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getHeader())) { 5682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos header.setText(entry.getHeader()); 5692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 5702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos header.setVisibility(View.GONE); 5712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 573dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView subHeader = (TextView) view.findViewById(R.id.sub_header); 57403ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getSubHeader())) { 5752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeader.setText(entry.getSubHeader()); 5762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 5772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeader.setVisibility(View.GONE); 5782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 580dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header); 5812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getSubHeaderIcon() != null) { 5822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeaderIcon.setImageDrawable(entry.getSubHeaderIcon()); 5832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 5842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeaderIcon.setVisibility(View.GONE); 5852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 587dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView text = (TextView) view.findViewById(R.id.text); 58803ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getText())) { 5892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos text.setText(entry.getText()); 5902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 5912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos text.setVisibility(View.GONE); 5922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 594dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text); 5952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getTextIcon() != null) { 5962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos textIcon.setImageDrawable(entry.getTextIcon()); 5972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 5982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos textIcon.setVisibility(View.GONE); 5992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getIntent() != null) { 6027d22b94ce50f7a65dd89d4533f2aa3a3392e7972Paul Soulos view.setOnClickListener(mOnClickListener); 6032ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos view.setTag(new EntryTag(entry.getId(), entry.getIntent())); 6042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 606a42ef76251778161d27bc07db214b8c81720e476Paul Soulos if (entry.getIntent() == null && entry.getEntryContextMenuInfo() == null) { 607a42ef76251778161d27bc07db214b8c81720e476Paul Soulos // Remove the click effect 608a42ef76251778161d27bc07db214b8c81720e476Paul Soulos view.setBackground(null); 609a42ef76251778161d27bc07db214b8c81720e476Paul Soulos } 610a42ef76251778161d27bc07db214b8c81720e476Paul Soulos 611ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // If only the header is visible, add a top margin to match icon's top margin. 612ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // Also increase the space below the header for visual comfort. 6134b943553afdb7286b33e4bc2481431e816c57967Paul Soulos if (header.getVisibility() == View.VISIBLE && subHeader.getVisibility() == View.GONE && 6144b943553afdb7286b33e4bc2481431e816c57967Paul Soulos text.getVisibility() == View.GONE) { 6154b943553afdb7286b33e4bc2481431e816c57967Paul Soulos RelativeLayout.LayoutParams headerLayoutParams = 6164b943553afdb7286b33e4bc2481431e816c57967Paul Soulos (RelativeLayout.LayoutParams) header.getLayoutParams(); 6174b943553afdb7286b33e4bc2481431e816c57967Paul Soulos headerLayoutParams.topMargin = (int) (getResources().getDimension( 618ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos R.dimen.expanding_entry_card_item_header_only_margin_top)); 619ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos headerLayoutParams.bottomMargin += (int) (getResources().getDimension( 620ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos R.dimen.expanding_entry_card_item_header_only_margin_bottom)); 6214b943553afdb7286b33e4bc2481431e816c57967Paul Soulos header.setLayoutParams(headerLayoutParams); 6224b943553afdb7286b33e4bc2481431e816c57967Paul Soulos } 6234b943553afdb7286b33e4bc2481431e816c57967Paul Soulos 624dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView alternateIcon = (ImageView) view.findViewById(R.id.icon_alternate); 625dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos if (entry.getAlternateIcon() != null && entry.getAlternateIntent() != null) { 626dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setImageDrawable(entry.getAlternateIcon()); 627dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setOnClickListener(mOnClickListener); 6282ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos alternateIcon.setTag(new EntryTag(entry.getId(), entry.getAlternateIntent())); 629dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setVisibility(View.VISIBLE); 630dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setContentDescription(entry.getAlternateContentDescription()); 631dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 632891bd2bad8de331a089466777cd054674261a969Paul Soulos // Expand the clickable area for alternate icon to be top to bottom and to end edge 633dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos // of the entry view 634dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos view.post(new Runnable() { 635dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos @Override 636dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos public void run() { 637dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final Rect alternateIconRect = new Rect(); 638dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.getHitRect(alternateIconRect); 639891bd2bad8de331a089466777cd054674261a969Paul Soulos 640891bd2bad8de331a089466777cd054674261a969Paul Soulos alternateIconRect.bottom = view.getHeight(); 641891bd2bad8de331a089466777cd054674261a969Paul Soulos alternateIconRect.top = 0; 642714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { 643891bd2bad8de331a089466777cd054674261a969Paul Soulos alternateIconRect.left = 0; 644714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos } else { 645891bd2bad8de331a089466777cd054674261a969Paul Soulos alternateIconRect.right = view.getWidth(); 646714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos } 647dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TouchDelegate touchDelegate = 648dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos new TouchDelegate(alternateIconRect, alternateIcon); 649dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos view.setTouchDelegate(touchDelegate); 650dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 651dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos }); 652dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 653dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 654edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos // Adjust the top padding size for entries with an invisible icon. The padding depends on 655edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos // if there is a sub header or text section 656edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos if (iconVisibility == View.INVISIBLE && 657edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos (!TextUtils.isEmpty(entry.getSubHeader()) || !TextUtils.isEmpty(entry.getText()))) { 658edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.setPaddingRelative(view.getPaddingStart(), 659edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos getResources().getDimensionPixelSize( 660edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos R.dimen.expanding_entry_card_item_no_icon_margin_top), 661edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.getPaddingEnd(), 662edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos view.getPaddingBottom()); 663edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos } else if (iconVisibility == View.INVISIBLE && TextUtils.isEmpty(entry.getSubHeader()) 664edd44f03e0e7aa57d4eb721147d4a3f3d2551c1aPaul Soulos && TextUtils.isEmpty(entry.getText())) { 665ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos view.setPaddingRelative(view.getPaddingStart(), 0, view.getPaddingEnd(), 666ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos view.getPaddingBottom()); 667ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos } 668ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos 6692a4207fb39330e840436215c896cde911489e111Paul Soulos view.setOnCreateContextMenuListener(mOnCreateContextMenuListener); 6702a4207fb39330e840436215c896cde911489e111Paul Soulos 6712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return view; 6722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 674c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos private void updateExpandCollapseButton(CharSequence buttonText, long duration) { 675c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos if (mIsExpanded) { 676c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos final ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandCollapseArrow, 677c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos "rotation", 180); 678c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.setDuration(duration); 679c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.start(); 6802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 681c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos final ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandCollapseArrow, 682c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos "rotation", 0); 683c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.setDuration(duration); 684c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.start(); 6852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 686c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateBadges(); 687c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos 6882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(buttonText); 6892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6916b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private void updateBadges() { 6926b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (mIsExpanded) { 6936b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.removeAllViews(); 6946b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } else { 6956b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos // Inflate badges if not yet created 6966b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (mBadges.size() < mEntries.size() - mCollapsedEntriesCount) { 6976b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos for (int i = mCollapsedEntriesCount; i < mEntries.size(); i++) { 6986b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos Drawable badgeDrawable = mEntries.get(i).get(0).getIcon(); 6996b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (badgeDrawable != null) { 7006b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos ImageView badgeView = new ImageView(getContext()); 7016b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos LinearLayout.LayoutParams badgeViewParams = new LinearLayout.LayoutParams( 7026b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos (int) getResources().getDimension( 7036b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_item_icon_width), 7046b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos (int) getResources().getDimension( 7056b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_item_icon_height)); 7066b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeViewParams.setMarginEnd((int) getResources().getDimension( 7076b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_badge_separator_margin)); 7086b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeView.setLayoutParams(badgeViewParams); 7096b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeView.setImageDrawable(badgeDrawable); 7106b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadges.add(badgeView); 7116b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7126b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7136b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7146b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.removeAllViews(); 7156b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos for (ImageView badge : mBadges) { 7166b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.addView(badge); 7176b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7186b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7196b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 7206b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos 7212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void expand() { 7220cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ChangeBounds boundsTransition = new ChangeBounds(); 7230cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.setDuration(DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS); 7240cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7250cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos Fade fadeIn = new Fade(Fade.IN); 7260cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos fadeIn.setDuration(DURATION_EXPAND_ANIMATION_FADE_IN); 7270cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos fadeIn.setStartDelay(DELAY_EXPAND_ANIMATION_FADE_IN); 7280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionSet transitionSet = new TransitionSet(); 7300cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(boundsTransition); 7310cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(fadeIn); 7320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7330cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ViewGroup transitionViewContainer = mAnimationViewGroup == null ? 7340cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos this : mAnimationViewGroup; 7350cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7360cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addListener(new TransitionListener() { 7370cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7380cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionStart(Transition transition) { 7390cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // The listener is used to turn off suppressing, the proper delta is not necessary 7400cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mListener.onExpand(0); 7410cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7420cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7430cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7440cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionEnd(Transition transition) { 7450cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7460cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7470cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7480cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionCancel(Transition transition) { 7490cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7500cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7510cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7520cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionPause(Transition transition) { 7530cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7540cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7550cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7560cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionResume(Transition transition) { 7570cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7580cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos }); 7590cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7600cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet); 7612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = true; 7630d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell // In order to insert new entries, we may need to inflate them for the first time 76460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(LayoutInflater.from(getContext())); 7652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos insertEntriesIntoViewGroup(); 766c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getCollapseButtonText(), 767c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS); 7682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void collapse() { 7710cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final int startingHeight = mEntriesViewGroup.getMeasuredHeight(); 7722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = false; 773c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getExpandButtonText(), 774c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 7752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7760cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ChangeBounds boundsTransition = new ChangeBounds(); 7770cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 7782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7790cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ChangeScroll scrollTransition = new ChangeScroll(); 7800cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos scrollTransition.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 7810cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7820cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionSet transitionSet = new TransitionSet(); 7830cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(boundsTransition); 7840cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(scrollTransition); 7850cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7860cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ViewGroup transitionViewContainer = mAnimationViewGroup == null ? 7870cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos this : mAnimationViewGroup; 7880cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7890cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.addListener(new TransitionListener() { 7902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 7910cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionStart(Transition transition) { 7920cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos /* 7930cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos * onTransitionStart is called after the view hierarchy has been changed but before 7940cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos * the animation begins. 7950cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos */ 7960cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos int finishingHeight = mEntriesViewGroup.getMeasuredHeight(); 7970cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mListener.onCollapse(startingHeight - finishingHeight); 7982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7990cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8000cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8010cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionEnd(Transition transition) { 8020cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8030cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 8050cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionCancel(Transition transition) { 8060cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8070cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8080cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8090cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionPause(Transition transition) { 8100cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 8110cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8120cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 8130cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionResume(Transition transition) { 8142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos }); 8160cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8170cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet); 8180cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 8190cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos insertEntriesIntoViewGroup(); 8202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 8232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Returns whether the view is currently in its expanded state. 8242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 8252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public boolean isExpanded() { 8262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIsExpanded; 8272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 8292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 8302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the title text of this ExpandingEntryCardView. 8312fa690807a94708384789b211965bfc75b5ac38ePaul Soulos * @param title The title to set. A null title will result in the title being removed. 8322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 8332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setTitle(String title) { 8342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mTitleTextView == null) { 8352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Log.e(TAG, "mTitleTextView is null"); 8362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 8372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTitleTextView.setText(title); 8381321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos mTitleTextView.setVisibility(TextUtils.isEmpty(title) ? View.GONE : View.VISIBLE); 8391321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos findViewById(R.id.title_separator).setVisibility(TextUtils.isEmpty(title) ? 8401321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View.GONE : View.VISIBLE); 8411321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // If the title is set after children have been added, reset the top entry's padding to 8421321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // the default. Else if the title is cleared after children have been added, set 8431321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos // the extra top padding 8441321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos if (!TextUtils.isEmpty(title) && mEntriesViewGroup.getChildCount() > 0) { 8451321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View firstEntry = mEntriesViewGroup.getChildAt(0); 8461321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.setPadding(firstEntry.getPaddingLeft(), 8471321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 8481321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_item_padding_top), 8491321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingRight(), 8501321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingBottom()); 8511321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } else if (!TextUtils.isEmpty(title) && mEntriesViewGroup.getChildCount() > 0) { 8521321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos View firstEntry = mEntriesViewGroup.getChildAt(0); 8531321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.setPadding(firstEntry.getPaddingLeft(), 8541321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 8551321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_item_padding_top) + 8561321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos getResources().getDimensionPixelSize( 8571321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos R.dimen.expanding_entry_card_null_title_top_extra_padding), 8581321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingRight(), 8591321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos firstEntry.getPaddingBottom()); 8601321736e0b6f4da580aa77075dd3845c8781f460Paul Soulos } 8612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 862eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos 863eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos public boolean shouldShow() { 864eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos return mEntries != null && mEntries.size() > 0; 865eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 8662a4207fb39330e840436215c896cde911489e111Paul Soulos 8672a4207fb39330e840436215c896cde911489e111Paul Soulos public static final class EntryView extends RelativeLayout { 8682a4207fb39330e840436215c896cde911489e111Paul Soulos private EntryContextMenuInfo mEntryContextMenuInfo; 8692a4207fb39330e840436215c896cde911489e111Paul Soulos 8702a4207fb39330e840436215c896cde911489e111Paul Soulos public EntryView(Context context) { 8712a4207fb39330e840436215c896cde911489e111Paul Soulos super(context); 8722a4207fb39330e840436215c896cde911489e111Paul Soulos } 8732a4207fb39330e840436215c896cde911489e111Paul Soulos 8742a4207fb39330e840436215c896cde911489e111Paul Soulos public EntryView(Context context, AttributeSet attrs) { 8752a4207fb39330e840436215c896cde911489e111Paul Soulos super(context, attrs); 8762a4207fb39330e840436215c896cde911489e111Paul Soulos } 8772a4207fb39330e840436215c896cde911489e111Paul Soulos 8782a4207fb39330e840436215c896cde911489e111Paul Soulos public void setContextMenuInfo(EntryContextMenuInfo info) { 8792a4207fb39330e840436215c896cde911489e111Paul Soulos mEntryContextMenuInfo = info; 8802a4207fb39330e840436215c896cde911489e111Paul Soulos } 8812a4207fb39330e840436215c896cde911489e111Paul Soulos 8822a4207fb39330e840436215c896cde911489e111Paul Soulos @Override 8832a4207fb39330e840436215c896cde911489e111Paul Soulos protected ContextMenuInfo getContextMenuInfo() { 8842a4207fb39330e840436215c896cde911489e111Paul Soulos return mEntryContextMenuInfo; 8852a4207fb39330e840436215c896cde911489e111Paul Soulos } 8862a4207fb39330e840436215c896cde911489e111Paul Soulos } 8872a4207fb39330e840436215c896cde911489e111Paul Soulos 8882a4207fb39330e840436215c896cde911489e111Paul Soulos public static final class EntryContextMenuInfo implements ContextMenuInfo { 8892a4207fb39330e840436215c896cde911489e111Paul Soulos private final String mCopyText; 8902a4207fb39330e840436215c896cde911489e111Paul Soulos private final String mCopyLabel; 8912a4207fb39330e840436215c896cde911489e111Paul Soulos 8922a4207fb39330e840436215c896cde911489e111Paul Soulos public EntryContextMenuInfo(String copyText, String copyLabel) { 8932a4207fb39330e840436215c896cde911489e111Paul Soulos mCopyText = copyText; 8942a4207fb39330e840436215c896cde911489e111Paul Soulos mCopyLabel = copyLabel; 8952a4207fb39330e840436215c896cde911489e111Paul Soulos } 8962a4207fb39330e840436215c896cde911489e111Paul Soulos 8972a4207fb39330e840436215c896cde911489e111Paul Soulos public String getCopyText() { 8982a4207fb39330e840436215c896cde911489e111Paul Soulos return mCopyText; 8992a4207fb39330e840436215c896cde911489e111Paul Soulos } 9002a4207fb39330e840436215c896cde911489e111Paul Soulos 9012a4207fb39330e840436215c896cde911489e111Paul Soulos public String getCopyLabel() { 9022a4207fb39330e840436215c896cde911489e111Paul Soulos return mCopyLabel; 9032a4207fb39330e840436215c896cde911489e111Paul Soulos } 9042a4207fb39330e840436215c896cde911489e111Paul Soulos } 9052ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9062ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos static final class EntryTag { 9072ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos private final int mId; 9082ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos private final Intent mIntent; 9092ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9102ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public EntryTag(int id, Intent intent) { 9112ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mId = id; 9122ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos mIntent = intent; 9132ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 9142ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9152ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public int getId() { 9162ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mId; 9172ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 9182ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos 9192ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos public Intent getIntent() { 9202ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos return mIntent; 9212ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 9222ed2a73d15bd80bced18e5924d3f84c8a9e5e5a5Paul Soulos } 9232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos} 924