ExpandingEntryCardView.java revision 0cda9aeb01f1922fce2a9e87ae4c0146c177b4f0
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
182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.Context;
192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.Intent;
202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.res.Resources;
217b0b0ce616c6c2fa149918c112128388712f5657Paul Soulosimport android.graphics.ColorFilter;
22dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulosimport android.graphics.Rect;
232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.graphics.drawable.Drawable;
242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.text.TextUtils;
250cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.ChangeBounds;
260cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.ChangeScroll;
270cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Fade;
280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Transition;
290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.Transition.TransitionListener;
300cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.TransitionManager;
310cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport android.transition.TransitionSet;
322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.AttributeSet;
332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.Log;
342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.LayoutInflater;
35dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulosimport android.view.TouchDelegate;
362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.View;
372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.ViewGroup;
382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.ImageView;
392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.LinearLayout;
402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.TextView;
412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
420cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulosimport com.android.contacts.R;
430cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.ArrayList;
452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.List;
462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos/**
482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Display entries in a LinearLayout that can be expanded to show all entries.
492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */
502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulospublic class ExpandingEntryCardView extends LinearLayout {
512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private static final String TAG = "ExpandingEntryCardView";
530cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos    private static final int DURATION_EXPAND_ANIMATION_FADE_IN = 200;
540cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos    private static final int DELAY_EXPAND_ANIMATION_FADE_IN = 100;
550cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
560cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos    public static final int DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS = 300;
570cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos    public static final int DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS = 300;
582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Entry data.
612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public static final class Entry {
632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
64ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos        private final int mViewId;
652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final Drawable mIcon;
662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final String mHeader;
672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final String mSubHeader;
682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final Drawable mSubHeaderIcon;
692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final String mText;
702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final Drawable mTextIcon;
712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final Intent mIntent;
72dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        private final Drawable mAlternateIcon;
73dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        private final Intent mAlternateIntent;
74dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        private final String mAlternateContentDescription;
7548ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos        private final boolean mShouldApplyColor;
762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final boolean mIsEditable;
772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
78ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos        public Entry(int viewId, Drawable icon, String header, String subHeader, String text,
79dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                Intent intent, Drawable alternateIcon, Intent alternateIntent,
80dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                String alternateContentDescription, boolean shouldApplyColor,
81dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                boolean isEditable) {
82dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            this(viewId, icon, header, subHeader, null, text, null, intent, alternateIcon,
83dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    alternateIntent, alternateContentDescription, shouldApplyColor, isEditable);
842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
86ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos        public Entry(int viewId, Drawable mainIcon, String header, String subHeader,
872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                Drawable subHeaderIcon, String text, Drawable textIcon, Intent intent,
88dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                Drawable alternateIcon, Intent alternateIntent, String alternateContentDescription,
8948ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos                boolean shouldApplyColor, boolean isEditable) {
90ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos            mViewId = viewId;
912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mIcon = mainIcon;
922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mHeader = header;
932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mSubHeader = subHeader;
942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mSubHeaderIcon = subHeaderIcon;
952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mText = text;
962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mTextIcon = textIcon;
972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mIntent = intent;
98dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            mAlternateIcon = alternateIcon;
99dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            mAlternateIntent = alternateIntent;
100dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            mAlternateContentDescription = alternateContentDescription;
10148ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos            mShouldApplyColor = shouldApplyColor;
1022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mIsEditable = isEditable;
1032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Drawable getIcon() {
1062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mIcon;
1072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        String getHeader() {
1102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mHeader;
1112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        String getSubHeader() {
1142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mSubHeader;
1152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Drawable getSubHeaderIcon() {
1182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mSubHeaderIcon;
1192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        public String getText() {
1222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mText;
1232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Drawable getTextIcon() {
1262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mTextIcon;
1272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Intent getIntent() {
1302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mIntent;
1312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
133dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        Drawable getAlternateIcon() {
134dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            return mAlternateIcon;
135dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        }
136dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos
137dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        Intent getAlternateIntent() {
138dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            return mAlternateIntent;
139dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        }
140dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos
141dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        String getAlternateContentDescription() {
142dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            return mAlternateContentDescription;
143dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        }
144dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos
14548ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos        boolean shouldApplyColor() {
14648ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos            return mShouldApplyColor;
14748ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos        }
14848ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos
1492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        boolean isEditable() {
1502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mIsEditable;
1512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
152ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos
153ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos        int getViewId() {
154ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos            return mViewId;
155ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos        }
1562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
1572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
158e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell    public interface ExpandingEntryCardViewListener {
159e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell        void onCollapse(int heightDelta);
1600cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        void onExpand(int heightDelta);
161e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell    }
162e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell
1632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private View mExpandCollapseButton;
1642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private TextView mExpandCollapseTextView;
1652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private TextView mTitleTextView;
1662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private CharSequence mExpandButtonText;
1672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private CharSequence mCollapseButtonText;
1682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private OnClickListener mOnClickListener;
1692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private boolean mIsExpanded = false;
1702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private int mCollapsedEntriesCount;
171e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell    private ExpandingEntryCardViewListener mListener;
17260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    private List<List<Entry>> mEntries;
17360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    private int mNumEntries = 0;
17460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    private boolean mAllEntriesInflated = false;
17560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    private List<List<View>> mEntryViews;
1762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private LinearLayout mEntriesViewGroup;
1777b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos    private final Drawable mCollapseArrowDrawable;
1787b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos    private final Drawable mExpandArrowDrawable;
1792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private int mThemeColor;
1807b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos    private ColorFilter mThemeColorFilter;
18189966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos    private boolean mIsAlwaysExpanded;
1820cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos    /** The ViewGroup to run the expand/collapse animation on */
1830cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos    private ViewGroup mAnimationViewGroup;
1842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private final OnClickListener mExpandCollapseButtonListener = new OnClickListener() {
1862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        @Override
1872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        public void onClick(View v) {
1882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            if (mIsExpanded) {
1892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                collapse();
1902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            } else {
1912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                expand();
1922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
1932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    };
1952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public ExpandingEntryCardView(Context context) {
1970d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        this(context, null);
1982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
1992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public ExpandingEntryCardView(Context context, AttributeSet attrs) {
2012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        super(context, attrs);
2022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        LayoutInflater inflater = LayoutInflater.from(context);
2032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        View expandingEntryCardView = inflater.inflate(R.layout.expanding_entry_card_view, this);
2042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mEntriesViewGroup = (LinearLayout)
2052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                expandingEntryCardView.findViewById(R.id.content_area_linear_layout);
2062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mTitleTextView = (TextView) expandingEntryCardView.findViewById(R.id.title);
2077b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        mCollapseArrowDrawable =
2087b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos                getResources().getDrawable(R.drawable.expanding_entry_card_collapse_white_24);
2097b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        mExpandArrowDrawable =
2107b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos                getResources().getDrawable(R.drawable.expanding_entry_card_expand_white_24);
2117b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos
2127b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        mExpandCollapseButton = inflater.inflate(
2137b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos                R.layout.quickcontact_expanding_entry_card_button, this, false);
2147b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        mExpandCollapseTextView = (TextView) mExpandCollapseButton.findViewById(R.id.text);
2157b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        mExpandCollapseButton.setOnClickListener(mExpandCollapseButtonListener);
2167b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos
2177b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos
2182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
2212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Sets the Entry list to display.
2222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     *
2232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * @param entries The Entry list to display.
2242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
22560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    public void initialize(List<List<Entry>> entries, int numInitialVisibleEntries,
22689966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos            boolean isExpanded, boolean isAlwaysExpanded,
2270cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            ExpandingEntryCardViewListener listener, ViewGroup animationViewGroup) {
2282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
2292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mIsExpanded = isExpanded;
23089966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos        mIsAlwaysExpanded = isAlwaysExpanded;
23189966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos        // If isAlwaysExpanded is true, mIsExpanded should be true
23289966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos        mIsExpanded |= mIsAlwaysExpanded;
23360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        mEntryViews = new ArrayList<List<View>>(entries.size());
2340d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        mEntries = entries;
2356095369885edcca566a812b551886e29c7ff8039Brian Attwell        mNumEntries = 0;
2366095369885edcca566a812b551886e29c7ff8039Brian Attwell        mAllEntriesInflated = false;
23760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        for (List<Entry> entryList : mEntries) {
23860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            mNumEntries += entryList.size();
23960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            mEntryViews.add(new ArrayList<View>());
24060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        }
24160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        mCollapsedEntriesCount = Math.min(numInitialVisibleEntries, mNumEntries);
24260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        // Only show the head of each entry list if the initial visible number falls between the
24360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        // number of lists and the total number of entries
24460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        if (mCollapsedEntriesCount > mEntries.size()) {
24560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            mCollapsedEntriesCount = mEntries.size();
24660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        }
247e8ce6ee1c5ab9f4f3dd11526337c70a8867647d9Brian Attwell        mListener = listener;
2480cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        mAnimationViewGroup = animationViewGroup;
2490d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell
2507b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        if (mIsExpanded) {
2517b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            updateExpandCollapseButton(getCollapseButtonText());
25260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            inflateAllEntries(layoutInflater);
2537b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        } else {
2547b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            updateExpandCollapseButton(getExpandButtonText());
25560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            inflateInitialEntries(layoutInflater);
2562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        insertEntriesIntoViewGroup();
2587b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        applyColor();
2592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
2622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Sets the text for the expand button.
2632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     *
2642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * @param expandButtonText The expand button text.
2652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
2662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void setExpandButtonText(CharSequence expandButtonText) {
2672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mExpandButtonText = expandButtonText;
2682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mExpandCollapseTextView != null && !mIsExpanded) {
2692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mExpandCollapseTextView.setText(expandButtonText);
2702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
2742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Sets the text for the expand button.
2752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     *
2762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * @param expandButtonText The expand button text.
2772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
2782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void setCollapseButtonText(CharSequence expandButtonText) {
2792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mCollapseButtonText = expandButtonText;
2802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mExpandCollapseTextView != null && mIsExpanded) {
2812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mExpandCollapseTextView.setText(mCollapseButtonText);
2822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    @Override
2862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void setOnClickListener(OnClickListener listener) {
2872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mOnClickListener = listener;
2882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void insertEntriesIntoViewGroup() {
2912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mEntriesViewGroup.removeAllViews();
29260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos
2932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mIsExpanded) {
29460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            for (List<View> viewList : mEntryViews) {
29560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                for (View view : viewList) {
29660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                    addEntry(view);
29760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                }
29860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            }
29960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        } else {
30060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            for (int i = 0; i < mCollapsedEntriesCount; i++) {
30160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                addEntry(mEntryViews.get(i).get(0));
3022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
3032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        removeView(mExpandCollapseButton);
30660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        if (mCollapsedEntriesCount < mNumEntries
30789966b4ed8cc9d385e5ac6b4a7e9e08ada387eb0Paul Soulos                && mExpandCollapseButton.getParent() == null && !mIsAlwaysExpanded) {
3082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            addView(mExpandCollapseButton, -1);
3092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void addEntry(View entry) {
3132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mEntriesViewGroup.getChildCount() > 0) {
3140cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            mEntriesViewGroup.addView(createSeparator(entry));
3152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mEntriesViewGroup.addView(entry);
3172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3190cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos    private View createSeparator(View entry) {
3200cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        View separator = new View(getContext());
3210cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        separator.setBackgroundColor(getResources().getColor(
3220cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                R.color.expanding_entry_card_item_separator_color));
3230cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        LayoutParams layoutParams = generateDefaultLayoutParams();
3240cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        Resources resources = getResources();
3250cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        layoutParams.height = resources.getDimensionPixelSize(
3260cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                R.dimen.expanding_entry_card_item_separator_height);
3270cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        // The separator is aligned with the text in the entry. This is offset by a default
3280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        // margin. If there is an icon present, the icon's width and margin are added
3290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        int marginStart = resources.getDimensionPixelSize(
3300cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                R.dimen.expanding_entry_card_item_padding_start);
3310cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        ImageView entryIcon = (ImageView) entry.findViewById(R.id.icon);
3320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        if (entryIcon.getDrawable() != null) {
3330cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            int imageWidthAndMargin =
3340cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                    resources.getDimensionPixelSize(
3350cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                            R.dimen.expanding_entry_card_item_icon_width) +
3360cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                    resources.getDimensionPixelSize(
3370cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                            R.dimen.expanding_entry_card_item_image_spacing);
3380cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            marginStart += imageWidthAndMargin;
3390cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        }
3400cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
3410cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            layoutParams.rightMargin = marginStart;
3420cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        } else {
3430cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            layoutParams.leftMargin = marginStart;
3440cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        }
3450cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        separator.setLayoutParams(layoutParams);
3460cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        return separator;
3470cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos    }
3480cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
3492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private CharSequence getExpandButtonText() {
3502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (!TextUtils.isEmpty(mExpandButtonText)) {
3512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mExpandButtonText;
3522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
3532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            // Default to "See more".
3542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return getResources().getText(R.string.expanding_entry_card_view_see_more);
3552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private CharSequence getCollapseButtonText() {
3592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (!TextUtils.isEmpty(mCollapseButtonText)) {
3602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mCollapseButtonText;
3612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
3622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            // Default to "See less".
3632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return getResources().getText(R.string.expanding_entry_card_view_see_less);
3642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3670d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell    /**
36860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos     * Inflates the initial entries to be shown.
3690d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell     */
37060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    private void inflateInitialEntries(LayoutInflater layoutInflater) {
37160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        // If the number of collapsed entries equals total entries, inflate all
37260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        if (mCollapsedEntriesCount == mNumEntries) {
37360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            inflateAllEntries(layoutInflater);
37460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        } else {
37560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            // Otherwise inflate the top entry from each list
37660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            for (int i = 0; i < mCollapsedEntriesCount; i++) {
37760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                mEntryViews.get(i).add(createEntryView(layoutInflater, mEntries.get(i).get(0)));
37860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            }
37960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        }
38060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    }
38160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos
38260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    /**
38360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos     * Inflates all entries.
38460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos     */
38560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos    private void inflateAllEntries(LayoutInflater layoutInflater) {
38660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        if (mAllEntriesInflated) {
38760e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            return;
38860e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        }
38960e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        for (int i = 0; i < mEntries.size(); i++) {
39060e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            List<Entry> entryList = mEntries.get(i);
39160e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            List<View> viewList = mEntryViews.get(i);
39260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            for (int j = viewList.size(); j < entryList.size(); j++) {
39360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                viewList.add(createEntryView(layoutInflater, entryList.get(j)));
39460e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos            }
3952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
39660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        mAllEntriesInflated = true;
3972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3997b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos    public void setColorAndFilter(int color, ColorFilter colorFilter) {
4007b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        mThemeColor = color;
4017b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        mThemeColorFilter = colorFilter;
4027b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        applyColor();
4037b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos    }
4047b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos
4056095369885edcca566a812b551886e29c7ff8039Brian Attwell    public void setEntryHeaderColor(int color) {
4066095369885edcca566a812b551886e29c7ff8039Brian Attwell        if (mEntries != null) {
4076095369885edcca566a812b551886e29c7ff8039Brian Attwell            for (List<View> entryList : mEntryViews) {
4086095369885edcca566a812b551886e29c7ff8039Brian Attwell                for (View entryView : entryList) {
4096095369885edcca566a812b551886e29c7ff8039Brian Attwell                    TextView header = (TextView) entryView.findViewById(R.id.header);
4106095369885edcca566a812b551886e29c7ff8039Brian Attwell                    if (header != null) {
4116095369885edcca566a812b551886e29c7ff8039Brian Attwell                        header.setTextColor(color);
4126095369885edcca566a812b551886e29c7ff8039Brian Attwell                    }
4136095369885edcca566a812b551886e29c7ff8039Brian Attwell                }
4146095369885edcca566a812b551886e29c7ff8039Brian Attwell            }
4156095369885edcca566a812b551886e29c7ff8039Brian Attwell        }
4166095369885edcca566a812b551886e29c7ff8039Brian Attwell    }
4176095369885edcca566a812b551886e29c7ff8039Brian Attwell
4187b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos    /**
4197b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos     * The ColorFilter is passed in along with the color so that a new one only needs to be created
4207b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos     * once for the entire activity.
4217b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos     * 1. Title
4227b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos     * 2. Entry icons
4237b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos     * 3. Expand/Collapse Text
4247b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos     * 4. Expand/Collapse Button
4257b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos     */
4267b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos    public void applyColor() {
4277b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        if (mThemeColor != 0 && mThemeColorFilter != null) {
4287b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            // Title
4297b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            if (mTitleTextView != null) {
4307b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos                mTitleTextView.setTextColor(mThemeColor);
4317b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            }
4327b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos
4337b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            // Entry icons
4347b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            if (mEntries != null) {
43560e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                for (List<Entry> entryList : mEntries) {
43660e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                    for (Entry entry : entryList) {
43748ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos                        if (entry.shouldApplyColor()) {
43848ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos                            Drawable icon = entry.getIcon();
43948ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos                            if (icon != null) {
44048ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos                                icon.setColorFilter(mThemeColorFilter);
44148ebbaafcf467c072e4477c98ef2faba1c65af7ePaul Soulos                            }
44260e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos                        }
443dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                        Drawable alternateIcon = entry.getAlternateIcon();
444dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                        if (alternateIcon != null) {
445dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                            alternateIcon.setColorFilter(mThemeColorFilter);
446dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                        }
447eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos                    }
4487b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos                }
4497b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            }
4507b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos
4517b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            // Expand/Collapse
4527b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            mExpandCollapseTextView.setTextColor(mThemeColor);
4537b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            mCollapseArrowDrawable.setColorFilter(mThemeColorFilter);
4547b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            mExpandArrowDrawable.setColorFilter(mThemeColorFilter);
4557b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        }
4567b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos    }
4577b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos
458eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos    // TODO add accessibility content descriptions
4592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private View createEntryView(LayoutInflater layoutInflater, Entry entry) {
460dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        final View view = layoutInflater.inflate(
4612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                R.layout.expanding_entry_card_item, this, false);
4622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
463ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos        view.setId(entry.getViewId());
464ea5e0b715030f1b0e8015defd10842127a8a4121Paul Soulos
465dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        final ImageView icon = (ImageView) view.findViewById(R.id.icon);
466eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos        if (entry.getIcon() != null) {
467eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos            icon.setImageDrawable(entry.getIcon());
468eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos        } else {
469eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos            icon.setVisibility(View.GONE);
470eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos        }
4712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
472dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        final TextView header = (TextView) view.findViewById(R.id.header);
4732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getHeader() != null) {
4742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            header.setText(entry.getHeader());
4752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
4762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            header.setVisibility(View.GONE);
4772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
4782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
479dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        final TextView subHeader = (TextView) view.findViewById(R.id.sub_header);
4802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getSubHeader() != null) {
4812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            subHeader.setText(entry.getSubHeader());
4822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
4832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            subHeader.setVisibility(View.GONE);
4842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
4852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
486dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        final ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header);
4872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getSubHeaderIcon() != null) {
4882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            subHeaderIcon.setImageDrawable(entry.getSubHeaderIcon());
4892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
4902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            subHeaderIcon.setVisibility(View.GONE);
4912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
4922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
493dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        final TextView text = (TextView) view.findViewById(R.id.text);
4942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getText() != null) {
4952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            text.setText(entry.getText());
4962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
4972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            text.setVisibility(View.GONE);
4982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
4992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
500dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        final ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text);
5012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getTextIcon() != null) {
5022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            textIcon.setImageDrawable(entry.getTextIcon());
5032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
5042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            textIcon.setVisibility(View.GONE);
5052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
5062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
5072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getIntent() != null) {
5087d22b94ce50f7a65dd89d4533f2aa3a3392e7972Paul Soulos            view.setOnClickListener(mOnClickListener);
5097d22b94ce50f7a65dd89d4533f2aa3a3392e7972Paul Soulos            view.setTag(entry.getIntent());
5102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
5112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
512dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        final ImageView alternateIcon = (ImageView) view.findViewById(R.id.icon_alternate);
513dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        if (entry.getAlternateIcon() != null && entry.getAlternateIntent() != null) {
514dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            alternateIcon.setImageDrawable(entry.getAlternateIcon());
515dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            alternateIcon.setOnClickListener(mOnClickListener);
516dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            alternateIcon.setTag(entry.getAlternateIntent());
517dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            alternateIcon.setId(entry.getViewId());
518dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            alternateIcon.setVisibility(View.VISIBLE);
519dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            alternateIcon.setContentDescription(entry.getAlternateContentDescription());
520dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos
521dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            // Expand the clickable area for alternate icon to be top to bottom and to right edge
522dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            // of the entry view
523dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            view.post(new Runnable() {
524dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                @Override
525dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                public void run() {
526dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    final Rect entryRect = new Rect();
527dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    view.getHitRect(entryRect);
528dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos
529dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    final Rect alternateIconRect = new Rect();
530dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    alternateIcon.getHitRect(alternateIconRect);
531dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    alternateIconRect.bottom = entryRect.bottom;
532dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    alternateIconRect.top = entryRect.top;
533714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos                    if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
534714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos                        alternateIconRect.left = entryRect.left;
535714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos                    } else {
536714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos                        alternateIconRect.right = entryRect.right;
537714455bba22b99d168a2e864dfbc74a6e30dfdb6Paul Soulos                    }
538dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    final TouchDelegate touchDelegate =
539dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                            new TouchDelegate(alternateIconRect, alternateIcon);
540dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                    view.setTouchDelegate(touchDelegate);
541dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos                }
542dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos            });
543dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos        }
544dd7419d90cda5c52e81491bea3cf3c3f4e0535c7Paul Soulos
5452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        return view;
5462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
5472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
5482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void updateExpandCollapseButton(CharSequence buttonText) {
5497b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos        final Drawable arrow = mIsExpanded ? mCollapseArrowDrawable : mExpandArrowDrawable;
5502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
5517b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            mExpandCollapseTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, arrow,
5522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                    null);
5532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
5547b0b0ce616c6c2fa149918c112128388712f5657Paul Soulos            mExpandCollapseTextView.setCompoundDrawablesWithIntrinsicBounds(arrow, null, null,
5552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                    null);
5562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
5572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mExpandCollapseTextView.setText(buttonText);
5582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
5592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
5602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void expand() {
5610cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        ChangeBounds boundsTransition = new ChangeBounds();
5620cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        boundsTransition.setDuration(DURATION_EXPAND_ANIMATION_CHANGE_BOUNDS);
5630cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5640cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        Fade fadeIn = new Fade(Fade.IN);
5650cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        fadeIn.setDuration(DURATION_EXPAND_ANIMATION_FADE_IN);
5660cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        fadeIn.setStartDelay(DELAY_EXPAND_ANIMATION_FADE_IN);
5670cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5680cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        TransitionSet transitionSet = new TransitionSet();
5690cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        transitionSet.addTransition(boundsTransition);
5700cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        transitionSet.addTransition(fadeIn);
5710cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5720cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        final ViewGroup transitionViewContainer = mAnimationViewGroup == null ?
5730cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                this : mAnimationViewGroup;
5740cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5750cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        transitionSet.addListener(new TransitionListener() {
5760cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            @Override
5770cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionStart(Transition transition) {
5780cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                // The listener is used to turn off suppressing, the proper delta is not necessary
5790cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                mListener.onExpand(0);
5800cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            }
5810cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5820cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            @Override
5830cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionEnd(Transition transition) {
5840cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            }
5850cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5860cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            @Override
5870cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionCancel(Transition transition) {
5880cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            }
5890cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5900cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            @Override
5910cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionPause(Transition transition) {
5920cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            }
5930cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5940cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            @Override
5950cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionResume(Transition transition) {
5960cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            }
5970cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        });
5980cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
5990cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet);
6002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
6012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mIsExpanded = true;
6020d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        // In order to insert new entries, we may need to inflate them for the first time
60360e5108e39e54d0a7e4c6924b33597d338be3fb9Paul Soulos        inflateAllEntries(LayoutInflater.from(getContext()));
6042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        insertEntriesIntoViewGroup();
6052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        updateExpandCollapseButton(getCollapseButtonText());
6062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
6072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
6082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void collapse() {
6090cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        final int startingHeight = mEntriesViewGroup.getMeasuredHeight();
6102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mIsExpanded = false;
6112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        updateExpandCollapseButton(getExpandButtonText());
6122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
6130cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        final ChangeBounds boundsTransition = new ChangeBounds();
6140cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        boundsTransition.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS);
6152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
6160cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        final ChangeScroll scrollTransition = new ChangeScroll();
6170cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        scrollTransition.setDuration(DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS);
6180cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6190cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        TransitionSet transitionSet = new TransitionSet();
6200cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        transitionSet.addTransition(boundsTransition);
6210cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        transitionSet.addTransition(scrollTransition);
6220cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6230cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        final ViewGroup transitionViewContainer = mAnimationViewGroup == null ?
6240cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                this : mAnimationViewGroup;
6250cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6260cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        boundsTransition.addListener(new TransitionListener() {
6272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            @Override
6280cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionStart(Transition transition) {
6290cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                /*
6300cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                 * onTransitionStart is called after the view hierarchy has been changed but before
6310cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                 * the animation begins.
6320cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                 */
6330cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                int finishingHeight = mEntriesViewGroup.getMeasuredHeight();
6340cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos                mListener.onCollapse(startingHeight - finishingHeight);
6352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
6360cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6370cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            @Override
6380cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionEnd(Transition transition) {
6390cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            }
6400cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            @Override
6420cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionCancel(Transition transition) {
6430cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            }
6440cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6450cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            @Override
6460cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionPause(Transition transition) {
6470cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            }
6480cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6490cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            @Override
6500cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos            public void onTransitionResume(Transition transition) {
6512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
6522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        });
6530cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6540cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        TransitionManager.beginDelayedTransition(transitionViewContainer, transitionSet);
6550cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos
6560cda9aeb01f1922fce2a9e87ae4c0146c177b4f0Paul Soulos        insertEntriesIntoViewGroup();
6572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
6582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
6592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
6602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Returns whether the view is currently in its expanded state.
6612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
6622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public boolean isExpanded() {
6632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        return mIsExpanded;
6642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
6652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
6662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
6672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Sets the title text of this ExpandingEntryCardView.
6682fa690807a94708384789b211965bfc75b5ac38ePaul Soulos     * @param title The title to set. A null title will result in the title being removed.
6692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
6702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void setTitle(String title) {
6712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mTitleTextView == null) {
6722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            Log.e(TAG, "mTitleTextView is null");
6732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
6742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (title == null) {
6752fa690807a94708384789b211965bfc75b5ac38ePaul Soulos            mTitleTextView.setVisibility(View.GONE);
676f5cc63f9f25f8d75a524202d2bd4f7d388d787a8Paul Soulos            findViewById(R.id.title_separator).setVisibility(View.GONE);
6772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
6782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mTitleTextView.setText(title);
6792fa690807a94708384789b211965bfc75b5ac38ePaul Soulos        mTitleTextView.setVisibility(View.VISIBLE);
680f5cc63f9f25f8d75a524202d2bd4f7d388d787a8Paul Soulos        findViewById(R.id.title_separator).setVisibility(View.VISIBLE);
6812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
682eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos
683eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos    public boolean shouldShow() {
684eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos        return mEntries != null && mEntries.size() > 0;
685eb64a4b5c51b39fe56ba4ef97dfff73fdcdf8c75Paul Soulos    }
6862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos}
687