ExpandingEntryCardView.java revision 0d49d81a3df2eea40dfe57570767c7661463f2dc
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 com.android.contacts.R;
192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.animation.Animator;
212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.animation.AnimatorListenerAdapter;
222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.animation.ValueAnimator;
232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.Context;
242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.Intent;
252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.content.res.Resources;
262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.graphics.drawable.Drawable;
272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.text.TextUtils;
282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.AttributeSet;
292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.util.Log;
302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.LayoutInflater;
312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.View;
322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.view.ViewGroup;
3371032f3fb7038995297666602773ae023c1351c4Brian Attwellimport android.view.ViewTreeObserver;
3471032f3fb7038995297666602773ae023c1351c4Brian Attwellimport android.view.ViewTreeObserver.OnPreDrawListener;
352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.ImageView;
362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.LinearLayout;
372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport android.widget.TextView;
382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.ArrayList;
402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulosimport java.util.List;
412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos/**
432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos * Display entries in a LinearLayout that can be expanded to show all entries.
442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos */
452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulospublic class ExpandingEntryCardView extends LinearLayout {
462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private static final String TAG = "ExpandingEntryCardView";
482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Entry data.
512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public static final class Entry {
532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final Drawable mIcon;
552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final String mHeader;
562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final String mSubHeader;
572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final Drawable mSubHeaderIcon;
582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final String mText;
592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final Drawable mTextIcon;
602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final Intent mIntent;
612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        private final boolean mIsEditable;
622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        public Entry(Drawable icon, String header, String subHeader, String text,
642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                Intent intent, boolean isEditable) {
652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            this(icon, header, subHeader, null, text, null, intent, isEditable);
662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        public Entry(Drawable mainIcon, String header, String subHeader,
692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                Drawable subHeaderIcon, String text, Drawable textIcon, Intent intent,
702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                boolean isEditable) {
712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mIcon = mainIcon;
722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mHeader = header;
732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mSubHeader = subHeader;
742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mSubHeaderIcon = subHeaderIcon;
752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mText = text;
762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mTextIcon = textIcon;
772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mIntent = intent;
782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mIsEditable = isEditable;
792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Drawable getIcon() {
822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mIcon;
832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        String getHeader() {
862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mHeader;
872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        String getSubHeader() {
902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mSubHeader;
912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Drawable getSubHeaderIcon() {
942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mSubHeaderIcon;
952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        public String getText() {
982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mText;
992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Drawable getTextIcon() {
1022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mTextIcon;
1032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Intent getIntent() {
1062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mIntent;
1072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        boolean isEditable() {
1102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mIsEditable;
1112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
1132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private View mExpandCollapseButton;
1152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private TextView mExpandCollapseTextView;
1162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private TextView mTitleTextView;
1172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private CharSequence mExpandButtonText;
1182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private CharSequence mCollapseButtonText;
1192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private OnClickListener mOnClickListener;
1202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private boolean mIsExpanded = false;
1212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private int mCollapsedEntriesCount;
1220d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell    private List<Entry> mEntries;
1232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private List<View> mEntryViews;
1242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private LinearLayout mEntriesViewGroup;
1252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private int mThemeColor;
1262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private final OnClickListener mExpandCollapseButtonListener = new OnClickListener() {
1282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        @Override
1292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        public void onClick(View v) {
1302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            if (mIsExpanded) {
1312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                collapse();
1322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            } else {
1332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                expand();
1342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
1352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    };
1372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public ExpandingEntryCardView(Context context) {
1390d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        this(context, null);
1402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
1412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public ExpandingEntryCardView(Context context, AttributeSet attrs) {
1432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        super(context, attrs);
1442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        LayoutInflater inflater = LayoutInflater.from(context);
1452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        View expandingEntryCardView = inflater.inflate(R.layout.expanding_entry_card_view, this);
1462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mEntriesViewGroup = (LinearLayout)
1472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                expandingEntryCardView.findViewById(R.id.content_area_linear_layout);
1482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mTitleTextView = (TextView) expandingEntryCardView.findViewById(R.id.title);
1492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
1502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
1522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Sets the Entry list to display.
1532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     *
1542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * @param entries The Entry list to display.
1552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
1562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void initialize(List<Entry> entries, int numInitialVisibleEntries,
1572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            boolean isExpanded, int themeColor) {
1582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
1592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mIsExpanded = isExpanded;
1600d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        mEntries = entries;
1610d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        mEntryViews = new ArrayList<View>(entries.size());
1622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mCollapsedEntriesCount = Math.min(numInitialVisibleEntries, entries.size());
1630d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        mThemeColor = themeColor;
1640d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell
1652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mExpandCollapseButton == null) {
1662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            createExpandButton(layoutInflater);
1672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1680d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        inflateViewsIfNeeded(layoutInflater);
1692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        insertEntriesIntoViewGroup();
1702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
1712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
1732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Sets the text for the expand button.
1742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     *
1752d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * @param expandButtonText The expand button text.
1762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
1772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void setExpandButtonText(CharSequence expandButtonText) {
1782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mExpandButtonText = expandButtonText;
1792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mExpandCollapseTextView != null && !mIsExpanded) {
1802d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mExpandCollapseTextView.setText(expandButtonText);
1812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
1832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
1852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Sets the text for the expand button.
1862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     *
1872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * @param expandButtonText The expand button text.
1882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
1892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void setCollapseButtonText(CharSequence expandButtonText) {
1902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mCollapseButtonText = expandButtonText;
1912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mExpandCollapseTextView != null && mIsExpanded) {
1922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mExpandCollapseTextView.setText(mCollapseButtonText);
1932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
1942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
1952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
1962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    @Override
1972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void setOnClickListener(OnClickListener listener) {
1982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mOnClickListener = listener;
1992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void insertEntriesIntoViewGroup() {
2022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mEntriesViewGroup.removeAllViews();
2032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        for (int i = 0; i < mCollapsedEntriesCount; ++i) {
2042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            addEntry(mEntryViews.get(i));
2052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mIsExpanded) {
2072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            for (int i = mCollapsedEntriesCount; i < mEntryViews.size(); ++i) {
2082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                addEntry(mEntryViews.get(i));
2092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
2102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        removeView(mExpandCollapseButton);
2130d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        if (mCollapsedEntriesCount < mEntries.size()
2142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                && mExpandCollapseButton.getParent() == null) {
2152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            addView(mExpandCollapseButton, -1);
2162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void addEntry(View entry) {
2202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mEntriesViewGroup.getChildCount() > 0) {
2212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            View separator = new View(getContext());
2222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            separator.setBackgroundColor(getResources().getColor(
2232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                    R.color.expanding_entry_card_item_separator_color));
2242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            LayoutParams layoutParams = generateDefaultLayoutParams();
2252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            Resources resources = getResources();
2262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            layoutParams.height = resources.getDimensionPixelSize(
2272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                    R.dimen.expanding_entry_card_item_separator_height);
2282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
2292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                layoutParams.rightMargin = resources.getDimensionPixelSize(
2302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                        R.dimen.expanding_entry_card_item_padding_start);
2312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                layoutParams.leftMargin = resources.getDimensionPixelSize(
2322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                        R.dimen.expanding_entry_card_item_padding_end);
2332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            } else {
2342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                layoutParams.leftMargin = resources.getDimensionPixelSize(
2352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                        R.dimen.expanding_entry_card_item_padding_start);
2362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                layoutParams.rightMargin = resources.getDimensionPixelSize(
2372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                        R.dimen.expanding_entry_card_item_padding_end);
2382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
2392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            separator.setLayoutParams(layoutParams);
2402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mEntriesViewGroup.addView(separator);
2412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mEntriesViewGroup.addView(entry);
2432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private CharSequence getExpandButtonText() {
2462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (!TextUtils.isEmpty(mExpandButtonText)) {
2472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mExpandButtonText;
2482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
2492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            // Default to "See more".
2502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return getResources().getText(R.string.expanding_entry_card_view_see_more);
2512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private CharSequence getCollapseButtonText() {
2552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (!TextUtils.isEmpty(mCollapseButtonText)) {
2562d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return mCollapseButtonText;
2572d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
2582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            // Default to "See less".
2592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            return getResources().getText(R.string.expanding_entry_card_view_see_less);
2602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2612d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2622d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2632d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void createExpandButton(LayoutInflater layoutInflater) {
2642d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mExpandCollapseButton = layoutInflater.inflate(
2652d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                R.layout.quickcontact_expanding_entry_card_button, this, false);
2662d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mExpandCollapseTextView = (TextView) mExpandCollapseButton.findViewById(R.id.text);
2672d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mIsExpanded) {
2682d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            updateExpandCollapseButton(getCollapseButtonText());
2692d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
2702d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            updateExpandCollapseButton(getExpandButtonText());
2712d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2722d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mExpandCollapseButton.setOnClickListener(mExpandCollapseButtonListener);
2732d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2742d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2750d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell    /**
2760d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell     * Lazily inflate the number of views currently needed, and bind data from
2770d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell     * mEntries into these views.
2780d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell     */
2790d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell    private void inflateViewsIfNeeded(LayoutInflater layoutInflater) {
2800d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        final int viewsToInflate = mIsExpanded ?  mEntries.size() : mCollapsedEntriesCount;
2810d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        for (int i = mEntryViews.size(); i < viewsToInflate; i++) {
2820d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell            mEntryViews.add(createEntryView(layoutInflater, mEntries.get(i)));
2832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
2852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private View createEntryView(LayoutInflater layoutInflater, Entry entry) {
2872d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        View view = layoutInflater.inflate(
2882d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                R.layout.expanding_entry_card_item, this, false);
2892d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2902d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        ImageView icon = (ImageView) view.findViewById(R.id.icon);
2912d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        icon.setImageDrawable(entry.getIcon());
2922d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
2932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        TextView header = (TextView) view.findViewById(R.id.header);
2942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getHeader() != null) {
2952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            header.setText(entry.getHeader());
2962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
2972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            header.setVisibility(View.GONE);
2982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
2992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        TextView subHeader = (TextView) view.findViewById(R.id.sub_header);
3012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getSubHeader() != null) {
3022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            subHeader.setText(entry.getSubHeader());
3032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
3042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            subHeader.setVisibility(View.GONE);
3052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header);
3082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getSubHeaderIcon() != null) {
3092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            subHeaderIcon.setImageDrawable(entry.getSubHeaderIcon());
3102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
3112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            subHeaderIcon.setVisibility(View.GONE);
3122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        TextView text = (TextView) view.findViewById(R.id.text);
3152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getText() != null) {
3162d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            text.setText(entry.getText());
3172d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
3182d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            text.setVisibility(View.GONE);
3192d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text);
3222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getTextIcon() != null) {
3232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            textIcon.setImageDrawable(entry.getTextIcon());
3242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
3252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            textIcon.setVisibility(View.GONE);
3262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (entry.getIntent() != null) {
3292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            View entryLayout = view.findViewById(R.id.entry_layout);
3302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            entryLayout.setOnClickListener(mOnClickListener);
3312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            entryLayout.setTag(entry.getIntent());
3322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        return view;
3352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void updateExpandCollapseButton(CharSequence buttonText) {
3382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        int resId = mIsExpanded ? R.drawable.expanding_entry_card_collapse_white_24
3392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                : R.drawable.expanding_entry_card_expand_white_24;
3402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        // TODO: apply color theme to the drawable
3412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        Drawable drawable = getResources().getDrawable(resId);
3422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
3432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mExpandCollapseTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable,
3442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                    null);
3452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        } else {
3462d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mExpandCollapseTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null,
3472d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                    null);
3482d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
3492d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mExpandCollapseTextView.setText(buttonText);
3502d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3512d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3522d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void expand() {
3532d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        final int startingHeight = mEntriesViewGroup.getHeight();
3542d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3552d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mIsExpanded = true;
3560d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        // In order to insert new entries, we may need to inflate them for the first time
3570d49d81a3df2eea40dfe57570767c7661463f2dcBrian Attwell        inflateViewsIfNeeded(LayoutInflater.from(getContext()));
3582d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        insertEntriesIntoViewGroup();
3592d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        updateExpandCollapseButton(getCollapseButtonText());
3602d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
36171032f3fb7038995297666602773ae023c1351c4Brian Attwell        // When expanding, all the TextViews haven't been laid out yet. Therefore,
36271032f3fb7038995297666602773ae023c1351c4Brian Attwell        // calling measure() would return an incorrect result. Therefore, we need a pre draw
36371032f3fb7038995297666602773ae023c1351c4Brian Attwell        // listener.
36471032f3fb7038995297666602773ae023c1351c4Brian Attwell        final ViewTreeObserver observer = mEntriesViewGroup.getViewTreeObserver();
36571032f3fb7038995297666602773ae023c1351c4Brian Attwell        observer.addOnPreDrawListener(new OnPreDrawListener() {
36671032f3fb7038995297666602773ae023c1351c4Brian Attwell            @Override
36771032f3fb7038995297666602773ae023c1351c4Brian Attwell            public boolean onPreDraw() {
36871032f3fb7038995297666602773ae023c1351c4Brian Attwell                if (observer.isAlive()) {
36971032f3fb7038995297666602773ae023c1351c4Brian Attwell                    mEntriesViewGroup.getViewTreeObserver().removeOnPreDrawListener(this);
37071032f3fb7038995297666602773ae023c1351c4Brian Attwell                }
37171032f3fb7038995297666602773ae023c1351c4Brian Attwell                createExpandAnimator(startingHeight, mEntriesViewGroup.getHeight()).start();
37271032f3fb7038995297666602773ae023c1351c4Brian Attwell                // Do not draw the final frame of the animation immediately.
37371032f3fb7038995297666602773ae023c1351c4Brian Attwell                return false;
37471032f3fb7038995297666602773ae023c1351c4Brian Attwell            }
37571032f3fb7038995297666602773ae023c1351c4Brian Attwell        });
3762d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3772d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3782d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private void collapse() {
3792d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        int startingHeight = mEntriesViewGroup.getHeight();
38071032f3fb7038995297666602773ae023c1351c4Brian Attwell        int finishHeight = measureCollapsedViewGroupHeight();
3812d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3822d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mIsExpanded = false;
3832d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        updateExpandCollapseButton(getExpandButtonText());
3842d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        createExpandAnimator(startingHeight, finishHeight).start();
3852d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3862d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
38771032f3fb7038995297666602773ae023c1351c4Brian Attwell    private int measureCollapsedViewGroupHeight() {
38871032f3fb7038995297666602773ae023c1351c4Brian Attwell        if (mCollapsedEntriesCount == 0) {
38971032f3fb7038995297666602773ae023c1351c4Brian Attwell            return 0;
39071032f3fb7038995297666602773ae023c1351c4Brian Attwell        }
39171032f3fb7038995297666602773ae023c1351c4Brian Attwell        final View bottomCollapsedView = mEntryViews.get(mCollapsedEntriesCount - 1);
39271032f3fb7038995297666602773ae023c1351c4Brian Attwell        return bottomCollapsedView.getTop() + bottomCollapsedView.getHeight();
3932d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
3942d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
3952d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
3962d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Create ValueAnimator that performs an expand animation on the content LinearLayout.
3972d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     *
3982d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * The animation needs to be performed manually using a ValueAnimator, since LinearLayout
3992d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * doesn't have a single set-able height property (ie, no setHeight()).
4002d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
4012d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    private ValueAnimator createExpandAnimator(int start, int end) {
4022d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        ValueAnimator animator = ValueAnimator.ofInt(start, end);
4032d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4042d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            @Override
4052d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            public void onAnimationUpdate(ValueAnimator valueAnimator) {
4062d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                int value = (Integer) valueAnimator.getAnimatedValue();
4072d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                ViewGroup.LayoutParams layoutParams = mEntriesViewGroup.getLayoutParams();
4082d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                layoutParams.height = value;
4092d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                mEntriesViewGroup.setLayoutParams(layoutParams);
4102d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
4112d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        });
4122d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        animator.addListener(new AnimatorListenerAdapter() {
4132d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            @Override
4142d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            public void onAnimationEnd(Animator animation) {
4152d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos                insertEntriesIntoViewGroup();
41671032f3fb7038995297666602773ae023c1351c4Brian Attwell                // Now that the animation is done, stop using a fixed height.
41771032f3fb7038995297666602773ae023c1351c4Brian Attwell                ViewGroup.LayoutParams layoutParams = mEntriesViewGroup.getLayoutParams();
41871032f3fb7038995297666602773ae023c1351c4Brian Attwell                layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
41971032f3fb7038995297666602773ae023c1351c4Brian Attwell                mEntriesViewGroup.setLayoutParams(layoutParams);
4202d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            }
4212d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        });
4222d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        return animator;
4232d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
4242d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
4252d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
4262d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Returns whether the view is currently in its expanded state.
4272d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
4282d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public boolean isExpanded() {
4292d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        return mIsExpanded;
4302d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
4312d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos
4322d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    /**
4332d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * Sets the title text of this ExpandingEntryCardView.
4342d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     * @param title The title to set. A null title will result in an empty string being set.
4352d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos     */
4362d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    public void setTitle(String title) {
4372d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (mTitleTextView == null) {
4382d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            Log.e(TAG, "mTitleTextView is null");
4392d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
4402d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        if (title == null) {
4412d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos            mTitleTextView.setText("");
4422d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        }
4432d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos        mTitleTextView.setText(title);
4442d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos    }
4452d48b5ae6664a7ae0ed9941f55fae9dc327bd640Paul Soulos}
446