ExpandingEntryCardView.java revision c205cf1d4db6a85f52175af0add8852d5e1f8605
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; 362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.LayoutInflater; 37dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulosimport android.view.TouchDelegate; 382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.View; 392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.ViewGroup; 40ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulosimport android.widget.FrameLayout; 412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.ImageView; 422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.LinearLayout; 434b943553afdb7286b33e4bc2481431e816c57967Paul Soulosimport android.widget.RelativeLayout; 442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.TextView; 452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 460cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport com.android.contacts.R; 470cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.ArrayList; 492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.List; 502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos/** 522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Display entries in a LinearLayout that can be expanded to show all entries. 532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 54ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulospublic class ExpandingEntryCardView extends CardView { 552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private static final String TAG = "ExpandingEntryCardView"; 570cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private static final int DURATION_EXPAND_ANIMATION_FADE_IN = 200; 580cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private static final int DELAY_EXPAND_ANIMATION_FADE_IN = 100; 590cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 600cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public static final int DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS = 300; 610cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public static final int DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS = 300; 622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Entry data. 652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public static final class Entry { 672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 68ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos private final int mViewId; 692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mIcon; 702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mHeader; 712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mSubHeader; 722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mSubHeaderIcon; 732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final String mText; 742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Drawable mTextIcon; 752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final Intent mIntent; 76dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final Drawable mAlternateIcon; 77dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final Intent mAlternateIntent; 78dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos private final String mAlternateContentDescription; 7948ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos private final boolean mShouldApplyColor; 802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final boolean mIsEditable; 812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 82ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos public Entry(int viewId, Drawable icon, String header, String subHeader, String text, 83dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Intent intent, Drawable alternateIcon, Intent alternateIntent, 84dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos String alternateContentDescription, boolean shouldApplyColor, 85dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos boolean isEditable) { 86dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos this(viewId, icon, header, subHeader, null, text, null, intent, alternateIcon, 87dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIntent, alternateContentDescription, shouldApplyColor, isEditable); 882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 90ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos public Entry(int viewId, Drawable mainIcon, String header, String subHeader, 912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable subHeaderIcon, String text, Drawable textIcon, Intent intent, 92dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable alternateIcon, Intent alternateIntent, String alternateContentDescription, 9348ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos boolean shouldApplyColor, boolean isEditable) { 94ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos mViewId = viewId; 952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIcon = mainIcon; 962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mHeader = header; 972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mSubHeader = subHeader; 982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mSubHeaderIcon = subHeaderIcon; 992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mText = text; 1002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTextIcon = textIcon; 1012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIntent = intent; 102dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateIcon = alternateIcon; 103dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateIntent = alternateIntent; 104dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos mAlternateContentDescription = alternateContentDescription; 10548ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos mShouldApplyColor = shouldApplyColor; 1062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsEditable = isEditable; 1072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getIcon() { 1102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIcon; 1112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos String getHeader() { 1142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mHeader; 1152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos String getSubHeader() { 1182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mSubHeader; 1192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getSubHeaderIcon() { 1222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mSubHeaderIcon; 1232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public String getText() { 1262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mText; 1272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Drawable getTextIcon() { 1302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mTextIcon; 1312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Intent getIntent() { 1342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIntent; 1352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 137dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable getAlternateIcon() { 138dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateIcon; 139dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 140dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 141dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Intent getAlternateIntent() { 142dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateIntent; 143dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 144dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 145dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos String getAlternateContentDescription() { 146dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos return mAlternateContentDescription; 147dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 148dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 14948ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos boolean shouldApplyColor() { 15048ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos return mShouldApplyColor; 15148ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos } 15248ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos 1532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos boolean isEditable() { 1542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIsEditable; 1552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 156ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos 157ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos int getViewId() { 158ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos return mViewId; 159ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos } 1602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 162e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell public interface ExpandingEntryCardViewListener { 163e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell void onCollapse(int heightDelta); 1640cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos void onExpand(int heightDelta); 165e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell } 166e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell 1672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private View mExpandCollapseButton; 1682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private TextView mExpandCollapseTextView; 1692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private TextView mTitleTextView; 1702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence mExpandButtonText; 1712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence mCollapseButtonText; 1722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private OnClickListener mOnClickListener; 1732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private boolean mIsExpanded = false; 1742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private int mCollapsedEntriesCount; 175e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell private ExpandingEntryCardViewListener mListener; 17660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private List<List<Entry>> mEntries; 17760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private int mNumEntries = 0; 17860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private boolean mAllEntriesInflated = false; 17960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private List<List<View>> mEntryViews; 1802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private LinearLayout mEntriesViewGroup; 181c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos private final ImageView mExpandCollapseArrow; 1822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private int mThemeColor; 1837b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos private ColorFilter mThemeColorFilter; 18489966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos private boolean mIsAlwaysExpanded; 1850cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos /** The ViewGroup to run the expand/collapse animation on */ 1860cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos private ViewGroup mAnimationViewGroup; 1876b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private LinearLayout mBadgeContainer; 1886b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private final List<ImageView> mBadges; 189ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos private LinearLayout mContainer; 1902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 1912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private final OnClickListener mExpandCollapseButtonListener = new OnClickListener() { 1922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 1932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void onClick(View v) { 1942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mIsExpanded) { 1952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos collapse(); 1962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 1972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos expand(); 1982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 1992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos }; 2012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public ExpandingEntryCardView(Context context) { 2030d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell this(context, null); 2042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public ExpandingEntryCardView(Context context, AttributeSet attrs) { 2072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos super(context, attrs); 2082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos LayoutInflater inflater = LayoutInflater.from(context); 2092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos View expandingEntryCardView = inflater.inflate(R.layout.expanding_entry_card_view, this); 2102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup = (LinearLayout) 2112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos expandingEntryCardView.findViewById(R.id.content_area_linear_layout); 2122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTitleTextView = (TextView) expandingEntryCardView.findViewById(R.id.title); 213ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos mContainer = (LinearLayout) expandingEntryCardView.findViewById(R.id.container); 2147b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 2157b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseButton = inflater.inflate( 2167b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos R.layout.quickcontact_expanding_entry_card_button, this, false); 2177b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseTextView = (TextView) mExpandCollapseButton.findViewById(R.id.text); 218c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos mExpandCollapseArrow = (ImageView) mExpandCollapseButton.findViewById(R.id.arrow); 2197b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseButton.setOnClickListener(mExpandCollapseButtonListener); 2206b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer = (LinearLayout) mExpandCollapseButton.findViewById(R.id.badge_container); 2217b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 2226b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadges = new ArrayList<ImageView>(); 2232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 2262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the Entry list to display. 2272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 2282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param entries The Entry list to display. 2292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 23060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos public void initialize(List<List<Entry>> entries, int numInitialVisibleEntries, 23189966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos boolean isExpanded, boolean isAlwaysExpanded, 2320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ExpandingEntryCardViewListener listener, ViewGroup animationViewGroup) { 2332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos LayoutInflater layoutInflater = LayoutInflater.from(getContext()); 2342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = isExpanded; 23589966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos mIsAlwaysExpanded = isAlwaysExpanded; 23689966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos // If isAlwaysExpanded is true, mIsExpanded should be true 23789966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos mIsExpanded |= mIsAlwaysExpanded; 23860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mEntryViews = new ArrayList<List<View>>(entries.size()); 2390d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell mEntries = entries; 2406095369885edcca566a812b551886e29c7ff8039Brian Attwell mNumEntries = 0; 2416095369885edcca566a812b551886e29c7ff8039Brian Attwell mAllEntriesInflated = false; 24260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<Entry> entryList : mEntries) { 24360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mNumEntries += entryList.size(); 24460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mEntryViews.add(new ArrayList<View>()); 24560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 24660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mCollapsedEntriesCount = Math.min(numInitialVisibleEntries, mNumEntries); 24760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // Only show the head of each entry list if the initial visible number falls between the 24860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // number of lists and the total number of entries 24960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mCollapsedEntriesCount > mEntries.size()) { 25060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mCollapsedEntriesCount = mEntries.size(); 25160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 252e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell mListener = listener; 2530cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mAnimationViewGroup = animationViewGroup; 2540d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell 2557b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mIsExpanded) { 256c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getCollapseButtonText(), /* duration = */ 0); 25760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(layoutInflater); 2587b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } else { 259c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getExpandButtonText(), /* duration = */ 0); 26060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateInitialEntries(layoutInflater); 2612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos insertEntriesIntoViewGroup(); 2637b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos applyColor(); 2642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 2672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the text for the expand button. 2682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 2692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param expandButtonText The expand button text. 2702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 2712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setExpandButtonText(CharSequence expandButtonText) { 2722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandButtonText = expandButtonText; 2732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mExpandCollapseTextView != null && !mIsExpanded) { 2742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(expandButtonText); 2752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 2792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the text for the expand button. 2802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * 2812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * @param expandButtonText The expand button text. 2822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 2832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setCollapseButtonText(CharSequence expandButtonText) { 2842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mCollapseButtonText = expandButtonText; 2852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mExpandCollapseTextView != null && mIsExpanded) { 2862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(mCollapseButtonText); 2872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 2912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setOnClickListener(OnClickListener listener) { 2922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mOnClickListener = listener; 2932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 2942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 2952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void insertEntriesIntoViewGroup() { 2962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup.removeAllViews(); 29760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos 2982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mIsExpanded) { 29960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<View> viewList : mEntryViews) { 30097ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (viewList != mEntryViews.get(0)) { 30197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos addSeparator(viewList.get(0)); 30297ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 30360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (View view : viewList) { 30460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos addEntry(view); 30560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 30660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 30760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } else { 30860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int i = 0; i < mCollapsedEntriesCount; i++) { 30997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (i > 0) { 31097ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos addSeparator(mEntryViews.get(i).get(0)); 31197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 31260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos addEntry(mEntryViews.get(i).get(0)); 3132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos removeView(mExpandCollapseButton); 31760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mCollapsedEntriesCount < mNumEntries 31889966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos && mExpandCollapseButton.getParent() == null && !mIsAlwaysExpanded) { 319ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos mContainer.addView(mExpandCollapseButton, -1); 3202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void addEntry(View entry) { 3242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mEntriesViewGroup.addView(entry); 3252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 32797ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos private void addSeparator(View entry) { 3280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos View separator = new View(getContext()); 329ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos Resources res = getResources(); 330ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos 331ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos separator.setBackgroundColor(res.getColor( 3320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos R.color.expanding_entry_card_item_separator_color)); 333ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( 334ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos ViewGroup.LayoutParams.MATCH_PARENT, 335ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_separator_height)); 3360cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // The separator is aligned with the text in the entry. This is offset by a default 3370cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // margin. If there is an icon present, the icon's width and margin are added 338ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos int marginStart = res.getDimensionPixelSize( 3390cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos R.dimen.expanding_entry_card_item_padding_start); 3400cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ImageView entryIcon = (ImageView) entry.findViewById(R.id.icon); 34197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (entryIcon.getVisibility() == View.VISIBLE) { 3420cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos int imageWidthAndMargin = 343ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_icon_width) + 344ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos res.getDimensionPixelSize(R.dimen.expanding_entry_card_item_image_spacing); 3450cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos marginStart += imageWidthAndMargin; 3460cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 34797ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos layoutParams.setMarginStart(marginStart); 3480cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos separator.setLayoutParams(layoutParams); 34997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos mEntriesViewGroup.addView(separator); 3500cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 3510cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 3522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence getExpandButtonText() { 3532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (!TextUtils.isEmpty(mExpandButtonText)) { 3542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mExpandButtonText; 3552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 3562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos // Default to "See more". 3572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return getResources().getText(R.string.expanding_entry_card_view_see_more); 3582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private CharSequence getCollapseButtonText() { 3622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (!TextUtils.isEmpty(mCollapseButtonText)) { 3632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mCollapseButtonText; 3642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 3652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos // Default to "See less". 3662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return getResources().getText(R.string.expanding_entry_card_view_see_less); 3672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 3692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 3700d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell /** 37160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos * Inflates the initial entries to be shown. 3720d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell */ 37360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private void inflateInitialEntries(LayoutInflater layoutInflater) { 37460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // If the number of collapsed entries equals total entries, inflate all 37560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mCollapsedEntriesCount == mNumEntries) { 37660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(layoutInflater); 37760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } else { 37860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos // Otherwise inflate the top entry from each list 37960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int i = 0; i < mCollapsedEntriesCount; i++) { 38097ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos mEntryViews.get(i).add(createEntryView(layoutInflater, mEntries.get(i).get(0), 38197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos /* showIcon = */ View.VISIBLE)); 38260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 38360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 38460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 38560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos 38660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos /** 38760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos * Inflates all entries. 38860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos */ 38960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos private void inflateAllEntries(LayoutInflater layoutInflater) { 39060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos if (mAllEntriesInflated) { 39160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos return; 39260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 39360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int i = 0; i < mEntries.size(); i++) { 39460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos List<Entry> entryList = mEntries.get(i); 39560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos List<View> viewList = mEntryViews.get(i); 39660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (int j = viewList.size(); j < entryList.size(); j++) { 39797ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos final int iconVisibility; 39897ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos final Entry entry = entryList.get(j); 39997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos // If the entry does not have an icon, mark gone. Else if it has an icon, show 40097ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos // for the first Entry in the list only 40197ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos if (entry.getIcon() == null) { 40297ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.GONE; 40397ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } else if (j == 0) { 40497ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.VISIBLE; 40597ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } else { 40697ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos iconVisibility = View.INVISIBLE; 40797ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos } 40897ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos viewList.add(createEntryView(layoutInflater, entry, iconVisibility)); 40960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 4102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 41160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos mAllEntriesInflated = true; 4122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 4147b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos public void setColorAndFilter(int color, ColorFilter colorFilter) { 4157b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mThemeColor = color; 4167b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mThemeColorFilter = colorFilter; 4177b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos applyColor(); 4187b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 4197b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 4206095369885edcca566a812b551886e29c7ff8039Brian Attwell public void setEntryHeaderColor(int color) { 4216095369885edcca566a812b551886e29c7ff8039Brian Attwell if (mEntries != null) { 4226095369885edcca566a812b551886e29c7ff8039Brian Attwell for (List<View> entryList : mEntryViews) { 4236095369885edcca566a812b551886e29c7ff8039Brian Attwell for (View entryView : entryList) { 4246095369885edcca566a812b551886e29c7ff8039Brian Attwell TextView header = (TextView) entryView.findViewById(R.id.header); 4256095369885edcca566a812b551886e29c7ff8039Brian Attwell if (header != null) { 4266095369885edcca566a812b551886e29c7ff8039Brian Attwell header.setTextColor(color); 4276095369885edcca566a812b551886e29c7ff8039Brian Attwell } 4286095369885edcca566a812b551886e29c7ff8039Brian Attwell } 4296095369885edcca566a812b551886e29c7ff8039Brian Attwell } 4306095369885edcca566a812b551886e29c7ff8039Brian Attwell } 4316095369885edcca566a812b551886e29c7ff8039Brian Attwell } 4326095369885edcca566a812b551886e29c7ff8039Brian Attwell 4337b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos /** 4347b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * The ColorFilter is passed in along with the color so that a new one only needs to be created 4357b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * once for the entire activity. 4367b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 1. Title 4377b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 2. Entry icons 4387b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 3. Expand/Collapse Text 4397b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos * 4. Expand/Collapse Button 4407b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos */ 4417b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos public void applyColor() { 4427b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mThemeColor != 0 && mThemeColorFilter != null) { 4437b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Title 4447b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mTitleTextView != null) { 4457b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mTitleTextView.setTextColor(mThemeColor); 4467b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 4477b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 4487b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Entry icons 4497b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos if (mEntries != null) { 45060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (List<Entry> entryList : mEntries) { 45160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos for (Entry entry : entryList) { 45248ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos if (entry.shouldApplyColor()) { 45348ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos Drawable icon = entry.getIcon(); 45448ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos if (icon != null) { 45548ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos icon.setColorFilter(mThemeColorFilter); 45648ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos } 45760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos } 458dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos Drawable alternateIcon = entry.getAlternateIcon(); 459dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos if (alternateIcon != null) { 460dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setColorFilter(mThemeColorFilter); 461dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 462eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 4637b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 4647b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 4657b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 4667b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos // Expand/Collapse 4677b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos mExpandCollapseTextView.setTextColor(mThemeColor); 468c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos mExpandCollapseArrow.setColorFilter(mThemeColorFilter); 4697b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 4707b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos } 4717b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos 47297ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos private View createEntryView(LayoutInflater layoutInflater, Entry entry, int iconVisibility) { 473dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final View view = layoutInflater.inflate( 4742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos R.layout.expanding_entry_card_item, this, false); 4752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 476ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos view.setId(entry.getViewId()); 477ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos 478dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView icon = (ImageView) view.findViewById(R.id.icon); 47997ed5019d75bd6afdfd5f3a8150161d9d9441275Paul Soulos icon.setVisibility(iconVisibility); 480eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos if (entry.getIcon() != null) { 481eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos icon.setImageDrawable(entry.getIcon()); 482eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 483dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView header = (TextView) view.findViewById(R.id.header); 48403ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getHeader())) { 4852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos header.setText(entry.getHeader()); 4862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 4872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos header.setVisibility(View.GONE); 4882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 490dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView subHeader = (TextView) view.findViewById(R.id.sub_header); 49103ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getSubHeader())) { 4922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeader.setText(entry.getSubHeader()); 4932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 4942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeader.setVisibility(View.GONE); 4952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 4962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 497dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header); 4982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getSubHeaderIcon() != null) { 4992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeaderIcon.setImageDrawable(entry.getSubHeaderIcon()); 5002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 5012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos subHeaderIcon.setVisibility(View.GONE); 5022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 504dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TextView text = (TextView) view.findViewById(R.id.text); 50503ece86bc2bda7f29aa2f8f2111035e4c6c6b871Paul Soulos if (!TextUtils.isEmpty(entry.getText())) { 5062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos text.setText(entry.getText()); 5072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 5082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos text.setVisibility(View.GONE); 5092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 511dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text); 5122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getTextIcon() != null) { 5132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos textIcon.setImageDrawable(entry.getTextIcon()); 5142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 5152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos textIcon.setVisibility(View.GONE); 5162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 5182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (entry.getIntent() != null) { 5197d22b94ce50f7a65dd89d4533f2aa3a3392e7972Paul Soulos view.setOnClickListener(mOnClickListener); 5207d22b94ce50f7a65dd89d4533f2aa3a3392e7972Paul Soulos view.setTag(entry.getIntent()); 5212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 523ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // If only the header is visible, add a top margin to match icon's top margin. 524ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // Also increase the space below the header for visual comfort. 5254b943553afdb7286b33e4bc2481431e816c57967Paul Soulos if (header.getVisibility() == View.VISIBLE && subHeader.getVisibility() == View.GONE && 5264b943553afdb7286b33e4bc2481431e816c57967Paul Soulos text.getVisibility() == View.GONE) { 5274b943553afdb7286b33e4bc2481431e816c57967Paul Soulos RelativeLayout.LayoutParams headerLayoutParams = 5284b943553afdb7286b33e4bc2481431e816c57967Paul Soulos (RelativeLayout.LayoutParams) header.getLayoutParams(); 5294b943553afdb7286b33e4bc2481431e816c57967Paul Soulos headerLayoutParams.topMargin = (int) (getResources().getDimension( 530ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos R.dimen.expanding_entry_card_item_header_only_margin_top)); 531ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos headerLayoutParams.bottomMargin += (int) (getResources().getDimension( 532ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos R.dimen.expanding_entry_card_item_header_only_margin_bottom)); 5334b943553afdb7286b33e4bc2481431e816c57967Paul Soulos header.setLayoutParams(headerLayoutParams); 5344b943553afdb7286b33e4bc2481431e816c57967Paul Soulos } 5354b943553afdb7286b33e4bc2481431e816c57967Paul Soulos 536dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final ImageView alternateIcon = (ImageView) view.findViewById(R.id.icon_alternate); 537dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos if (entry.getAlternateIcon() != null && entry.getAlternateIntent() != null) { 538dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setImageDrawable(entry.getAlternateIcon()); 539dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setOnClickListener(mOnClickListener); 540dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setTag(entry.getAlternateIntent()); 541dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setId(entry.getViewId()); 542dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setVisibility(View.VISIBLE); 543dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.setContentDescription(entry.getAlternateContentDescription()); 544dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 545891bd2bad8de331a089466777cd054674261a969Paul Soulos // Expand the clickable area for alternate icon to be top to bottom and to end edge 546dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos // of the entry view 547dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos view.post(new Runnable() { 548dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos @Override 549dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos public void run() { 550dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final Rect alternateIconRect = new Rect(); 551dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos alternateIcon.getHitRect(alternateIconRect); 552891bd2bad8de331a089466777cd054674261a969Paul Soulos 553891bd2bad8de331a089466777cd054674261a969Paul Soulos alternateIconRect.bottom = view.getHeight(); 554891bd2bad8de331a089466777cd054674261a969Paul Soulos alternateIconRect.top = 0; 555714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { 556891bd2bad8de331a089466777cd054674261a969Paul Soulos alternateIconRect.left = 0; 557714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos } else { 558891bd2bad8de331a089466777cd054674261a969Paul Soulos alternateIconRect.right = view.getWidth(); 559714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos } 560dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos final TouchDelegate touchDelegate = 561dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos new TouchDelegate(alternateIconRect, alternateIcon); 562dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos view.setTouchDelegate(touchDelegate); 563dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 564dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos }); 565dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos } 566dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos 567ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos // Decrease margin for entries that have an invisible icon 568ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos if (iconVisibility == View.INVISIBLE) { 569ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos view.setPaddingRelative(view.getPaddingStart(), 0, view.getPaddingEnd(), 570ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos view.getPaddingBottom()); 571ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos } 572ac9b31665c157e6aa7bce487a5467e8abd8224d5Paul Soulos 5732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return view; 5742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 576c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos private void updateExpandCollapseButton(CharSequence buttonText, long duration) { 577c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos if (mIsExpanded) { 578c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos final ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandCollapseArrow, 579c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos "rotation", 180); 580c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.setDuration(duration); 581c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.start(); 5822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } else { 583c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos final ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandCollapseArrow, 584c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos "rotation", 0); 585c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.setDuration(duration); 586c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos animator.start(); 5872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 588c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateBadges(); 589c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos 5902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mExpandCollapseTextView.setText(buttonText); 5912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 5922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 5936b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos private void updateBadges() { 5946b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (mIsExpanded) { 5956b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.removeAllViews(); 5966b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } else { 5976b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos // Inflate badges if not yet created 5986b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (mBadges.size() < mEntries.size() - mCollapsedEntriesCount) { 5996b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos for (int i = mCollapsedEntriesCount; i < mEntries.size(); i++) { 6006b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos Drawable badgeDrawable = mEntries.get(i).get(0).getIcon(); 6016b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos if (badgeDrawable != null) { 6026b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos ImageView badgeView = new ImageView(getContext()); 6036b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos LinearLayout.LayoutParams badgeViewParams = new LinearLayout.LayoutParams( 6046b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos (int) getResources().getDimension( 6056b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_item_icon_width), 6066b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos (int) getResources().getDimension( 6076b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_item_icon_height)); 6086b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeViewParams.setMarginEnd((int) getResources().getDimension( 6096b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos R.dimen.expanding_entry_card_badge_separator_margin)); 6106b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeView.setLayoutParams(badgeViewParams); 6116b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos badgeView.setImageDrawable(badgeDrawable); 6126b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadges.add(badgeView); 6136b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 6146b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 6156b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 6166b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.removeAllViews(); 6176b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos for (ImageView badge : mBadges) { 6186b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos mBadgeContainer.addView(badge); 6196b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 6206b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 6216b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos } 6226b6328915d66f0c5947badc3d1973c31f29eef62Paul Soulos 6232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void expand() { 6240cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos ChangeBounds boundsTransition = new ChangeBounds(); 6250cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.setDuration(DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS); 6260cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6270cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos Fade fadeIn = new Fade(Fade.IN); 6280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos fadeIn.setDuration(DURATION_EXPAND_ANIMATION_FADE_IN); 6290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos fadeIn.setStartDelay(DELAY_EXPAND_ANIMATION_FADE_IN); 6300cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6310cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionSet transitionSet = new TransitionSet(); 6320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(boundsTransition); 6330cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(fadeIn); 6340cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6350cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ViewGroup transitionViewContainer = mAnimationViewGroup == null ? 6360cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos this : mAnimationViewGroup; 6370cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6380cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addListener(new TransitionListener() { 6390cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 6400cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionStart(Transition transition) { 6410cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos // The listener is used to turn off suppressing, the proper delta is not necessary 6420cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mListener.onExpand(0); 6430cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 6440cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6450cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 6460cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionEnd(Transition transition) { 6470cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 6480cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6490cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 6500cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionCancel(Transition transition) { 6510cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 6520cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6530cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 6540cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionPause(Transition transition) { 6550cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 6560cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6570cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 6580cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionResume(Transition transition) { 6590cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 6600cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos }); 6610cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6620cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet); 6632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = true; 6650d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell // In order to insert new entries, we may need to inflate them for the first time 66660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos inflateAllEntries(LayoutInflater.from(getContext())); 6672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos insertEntriesIntoViewGroup(); 668c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getCollapseButtonText(), 669c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS); 6702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 6712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos private void collapse() { 6730cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final int startingHeight = mEntriesViewGroup.getMeasuredHeight(); 6742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mIsExpanded = false; 675c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos updateExpandCollapseButton(getExpandButtonText(), 676c205cf1d4db6a85f52175af0add8852d5e1f8605Paul Soulos DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 6772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6780cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ChangeBounds boundsTransition = new ChangeBounds(); 6790cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 6802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 6810cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ChangeScroll scrollTransition = new ChangeScroll(); 6820cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos scrollTransition.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS); 6830cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6840cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionSet transitionSet = new TransitionSet(); 6850cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(boundsTransition); 6860cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos transitionSet.addTransition(scrollTransition); 6870cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6880cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos final ViewGroup transitionViewContainer = mAnimationViewGroup == null ? 6890cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos this : mAnimationViewGroup; 6900cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 6910cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos boundsTransition.addListener(new TransitionListener() { 6922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 6930cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionStart(Transition transition) { 6940cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos /* 6950cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos * onTransitionStart is called after the view hierarchy has been changed but before 6960cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos * the animation begins. 6970cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos */ 6980cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos int finishingHeight = mEntriesViewGroup.getMeasuredHeight(); 6990cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos mListener.onCollapse(startingHeight - finishingHeight); 7002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7010cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7020cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7030cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionEnd(Transition transition) { 7040cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7050cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos @Override 7070cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionCancel(Transition transition) { 7080cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7090cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7100cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7110cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionPause(Transition transition) { 7120cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos } 7130cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7140cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos @Override 7150cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos public void onTransitionResume(Transition transition) { 7162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos }); 7180cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7190cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet); 7200cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos 7210cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos insertEntriesIntoViewGroup(); 7222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 7252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Returns whether the view is currently in its expanded state. 7262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 7272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public boolean isExpanded() { 7282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos return mIsExpanded; 7292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos 7312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos /** 7322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Sets the title text of this ExpandingEntryCardView. 7332fa690807a94708384789b211965bfc75b5ac38ePaul Soulos * @param title The title to set. A null title will result in the title being removed. 7342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */ 7352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos public void setTitle(String title) { 7362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (mTitleTextView == null) { 7372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos Log.e(TAG, "mTitleTextView is null"); 7382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos if (title == null) { 7402fa690807a94708384789b211965bfc75b5ac38ePaul Soulos mTitleTextView.setVisibility(View.GONE); 741f5cc63f9f25f8d75a524202d2bd4f7d388d787a8Paul Soulos findViewById(R.id.title_separator).setVisibility(View.GONE); 7422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 7432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos mTitleTextView.setText(title); 7442fa690807a94708384789b211965bfc75b5ac38ePaul Soulos mTitleTextView.setVisibility(View.VISIBLE); 745f5cc63f9f25f8d75a524202d2bd4f7d388d787a8Paul Soulos findViewById(R.id.title_separator).setVisibility(View.VISIBLE); 7462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos } 747eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos 748eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos public boolean shouldShow() { 749eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos return mEntries != null && mEntries.size() > 0; 750eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos } 7512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos} 752