11e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney/*
21e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * Copyright (C) 2009 The Android Open Source Project
31e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney *
41e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * Licensed under the Apache License, Version 2.0 (the "License");
51e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * you may not use this file except in compliance with the License.
61e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * You may obtain a copy of the License at
71e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney *
81e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney *      http://www.apache.org/licenses/LICENSE-2.0
91e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney *
101e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * Unless required by applicable law or agreed to in writing, software
111e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * distributed under the License is distributed on an "AS IS" BASIS,
121e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * See the License for the specific language governing permissions and
141e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * limitations under the License.
151e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney */
161e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
171e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneypackage com.android.quicksearchbox.ui;
181e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
191e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport com.android.quicksearchbox.R;
20fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport com.android.quicksearchbox.Source;
2193bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringertimport com.android.quicksearchbox.Suggestion;
22e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwoodimport com.android.quicksearchbox.util.Consumer;
23e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwoodimport com.android.quicksearchbox.util.NowOrLater;
241e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
251e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport android.content.Context;
26965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringertimport android.content.res.ColorStateList;
271e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport android.graphics.drawable.Drawable;
281cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwoodimport android.net.Uri;
29fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.text.Html;
30965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringertimport android.text.Spannable;
31965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringertimport android.text.SpannableString;
321e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport android.text.TextUtils;
33965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringertimport android.text.style.TextAppearanceSpan;
341e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport android.util.AttributeSet;
351e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport android.util.Log;
361e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport android.view.View;
371e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport android.widget.ImageView;
381e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinneyimport android.widget.TextView;
391e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
401e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney/**
411e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * View for the items in the suggestions list. This includes promoted suggestions,
421e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney * sources, and suggestions under each source.
431e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney */
4477909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringertpublic class DefaultSuggestionView extends BaseSuggestionView {
451e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
461e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    private static final boolean DBG = false;
471e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
4877909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert    private static final String VIEW_ID = "default";
495229b06f00d20aac76cd8519b37f2a579d61c54fMathew Inwood
5077909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert    private final String TAG = "QSB.DefaultSuggestionView";
51e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
5277909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert    private AsyncIcon mAsyncIcon1;
5377909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert    private AsyncIcon mAsyncIcon2;
541e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
551e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    public DefaultSuggestionView(Context context, AttributeSet attrs, int defStyle) {
561e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        super(context, attrs, defStyle);
5766ee1cc883f77fee930587503ecdcd8d18f12b23Mathew Inwood    }
581e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
591e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    public DefaultSuggestionView(Context context, AttributeSet attrs) {
601e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        super(context, attrs);
611e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    }
621e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
631e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    public DefaultSuggestionView(Context context) {
641e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        super(context);
651e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    }
661e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
671e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    @Override
681e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    protected void onFinishInflate() {
691e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        super.onFinishInflate();
701e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        mText1 = (TextView) findViewById(R.id.text1);
711e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        mText2 = (TextView) findViewById(R.id.text2);
7277909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert        mAsyncIcon1 = new AsyncIcon(mIcon1) {
73e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            // override default icon (when no other available) with default source icon
74e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            @Override
75e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            protected String getFallbackIconId(Source source) {
76e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                return source.getSourceIconUri().toString();
77e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            }
78e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            @Override
79e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            protected Drawable getFallbackIcon(Source source) {
80e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                return source.getSourceIcon();
81e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            }
82e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        };
8377909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert        mAsyncIcon2 = new AsyncIcon(mIcon2);
841e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    }
851e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
8677909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert    @Override
875229b06f00d20aac76cd8519b37f2a579d61c54fMathew Inwood    public void bindAsSuggestion(Suggestion suggestion, String userQuery) {
8877909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert        super.bindAsSuggestion(suggestion, userQuery);
8966ee1cc883f77fee930587503ecdcd8d18f12b23Mathew Inwood
9077909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert        CharSequence text1 = formatText(suggestion.getSuggestionText1(), suggestion);
91965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert        CharSequence text2 = suggestion.getSuggestionText2Url();
92965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert        if (text2 != null) {
93965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert            text2 = formatUrl(text2);
94965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert        } else {
9577909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert            text2 = formatText(suggestion.getSuggestionText2(), suggestion);
96965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert        }
97145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert        // If there is no text for the second line, allow the first line to be up to two lines
98bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert        if (TextUtils.isEmpty(text2)) {
99bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert            mText1.setSingleLine(false);
100bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert            mText1.setMaxLines(2);
101bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert            mText1.setEllipsize(TextUtils.TruncateAt.START);
102bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert        } else {
103bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert            mText1.setSingleLine(true);
104bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert            mText1.setMaxLines(1);
105bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert            mText1.setEllipsize(TextUtils.TruncateAt.MIDDLE);
106bf18086dbcdc3cbc50409940b58fbc3a7dcf3a88Bjorn Bringert        }
1071e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        setText1(text1);
1081e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        setText2(text2);
10977909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert        mAsyncIcon1.set(suggestion.getSuggestionSource(), suggestion.getSuggestionIcon1());
11077909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert        mAsyncIcon2.set(suggestion.getSuggestionSource(), suggestion.getSuggestionIcon2());
111fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert
112fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert        if (DBG) {
113fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert            Log.d(TAG, "bindAsSuggestion(), text1=" + text1 + ",text2=" + text2 + ",q='" +
1143bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert                    userQuery + ",fromHistory=" + isFromHistory(suggestion));
115145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert        }
1161e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    }
1171e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
118965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert    private CharSequence formatUrl(CharSequence url) {
119965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert        SpannableString text = new SpannableString(url);
120965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert        ColorStateList colors = getResources().getColorStateList(R.color.url_text);
121965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert        text.setSpan(new TextAppearanceSpan(null, 0, 0, colors, null),
122965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert                0, url.length(),
123965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
124965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert        return text;
125965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert    }
126965d98377ddfdc52b772c2444d840000b665e000Bjorn Bringert
12777909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert    private CharSequence formatText(String str, Suggestion suggestion) {
1282fb3a129925a42e72944b836e85a1a2d55a0d950Mathew Inwood        boolean isHtml = "html".equals(suggestion.getSuggestionFormat());
129fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        if (isHtml && looksLikeHtml(str)) {
130fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            return Html.fromHtml(str);
131fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        } else {
132fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            return str;
133fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        }
134fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    }
135fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert
136fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    private boolean looksLikeHtml(String str) {
137fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        if (TextUtils.isEmpty(str)) return false;
138fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        for (int i = str.length() - 1; i >= 0; i--) {
139fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            char c = str.charAt(i);
140fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            if (c == '>' || c == '&') return true;
141fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        }
142fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        return false;
143fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    }
144fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert
145dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert    /**
1461e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney     * Sets the drawable in an image view, makes sure the view is only visible if there
1471e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney     * is a drawable.
1481e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney     */
1491e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    private static void setViewDrawable(ImageView v, Drawable drawable) {
1501e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        // Set the icon even if the drawable is null, since we need to clear any
1511e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        // previous icon.
1521e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        v.setImageDrawable(drawable);
1531e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
1541e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        if (drawable == null) {
1551e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            v.setVisibility(View.GONE);
1561e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        } else {
1571e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            v.setVisibility(View.VISIBLE);
1581e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
1591e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            // This is a hack to get any animated drawables (like a 'working' spinner)
1601e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            // to animate. You have to setVisible true on an AnimationDrawable to get
1611e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            // it to start animating, but it must first have been false or else the
1621e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            // call to setVisible will be ineffective. We need to clear up the story
1631e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            // about animated drawables in the future, see http://b/1878430.
1641e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            drawable.setVisible(false, false);
1651e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney            drawable.setVisible(true, false);
1661e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney        }
1671e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney    }
1681e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney
169e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood    private class AsyncIcon {
170e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        private final ImageView mView;
171e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        private String mCurrentId;
172e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        private String mWantedId;
173e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
174e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        public AsyncIcon(ImageView view) {
175e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            mView = view;
176e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        }
177e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
1781cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood        public void set(final Source source, final String sourceIconId) {
1791cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood            if (sourceIconId != null) {
1801cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                // The iconId can just be a package-relative resource ID, which may overlap with
1811cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                // other packages. Make sure it's globally unique.
1821cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                Uri iconUri = source.getIconUri(sourceIconId);
1831cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                final String uniqueIconId = iconUri == null ? null : iconUri.toString();
1841cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                mWantedId = uniqueIconId;
185e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                if (!TextUtils.equals(mWantedId, mCurrentId)) {
1861cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                    if (DBG) Log.d(TAG, "getting icon Id=" + uniqueIconId);
1871cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                    NowOrLater<Drawable> icon = source.getIcon(sourceIconId);
188e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                    if (icon.haveNow()) {
189e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                        if (DBG) Log.d(TAG, "getIcon ready now");
1901cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                        handleNewDrawable(icon.getNow(), uniqueIconId, source);
191e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                    } else {
192e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                        // make sure old icon is not visible while new one is loaded
193e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                        if (DBG) Log.d(TAG , "getIcon getting later");
194e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                        clearDrawable();
195e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                        icon.getLater(new Consumer<Drawable>(){
196ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood                            @Override
197e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                            public boolean consume(Drawable icon) {
198e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                                if (DBG) {
1991cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                                    Log.d(TAG, "IconConsumer.consume got id " + uniqueIconId +
200e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                                            " want id " + mWantedId);
201e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                                }
202e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                                // ensure we have not been re-bound since the request was made.
2031cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                                if (TextUtils.equals(uniqueIconId, mWantedId)) {
2041cbbe20d1c148a7966a0b69b01b705da9e491de1Mathew Inwood                                    handleNewDrawable(icon, uniqueIconId, source);
205e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                                    return true;
206e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                                }
207e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                                return false;
208e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                            }});
209e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                    }
210e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                }
211e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            } else {
212e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                mWantedId = null;
213e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                handleNewDrawable(null, null, source);
214e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            }
215e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        }
216e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
217e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        private void handleNewDrawable(Drawable icon, String id, Source source) {
218e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            if (icon == null) {
219e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                mWantedId = getFallbackIconId(source);
220e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                if (TextUtils.equals(mWantedId, mCurrentId)) {
221e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                    return;
222e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                }
223e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood                icon = getFallbackIcon(source);
224e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            }
225e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            setDrawable(icon, id);
226e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        }
227e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
228e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        private void setDrawable(Drawable icon, String id) {
229e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            mCurrentId = id;
230e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            setViewDrawable(mView, icon);
231e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        }
232e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
233e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        private void clearDrawable() {
234e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            mCurrentId = null;
235e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            mView.setImageDrawable(null);
236e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        }
237e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
238e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        protected String getFallbackIconId(Source source) {
239e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            return null;
240e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        }
241e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
242e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        protected Drawable getFallbackIcon(Source source) {
243e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood            return null;
244e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood        }
245e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood
246e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood    }
247fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood
24877909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert    public static class Factory extends SuggestionViewInflater {
24977909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert        public Factory(Context context) {
25077909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert            super(VIEW_ID, DefaultSuggestionView.class, R.layout.suggestion, context);
25177909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert        }
25277909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert    }
25377909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert
2541e938ea2f5edefab446b9562b316bc5dc72adebbBryan Mawhinney}
255