SearchActivityViewTwoPane.java revision 73a375928e0b8f0b2bfa09e4b252cfcbdad4ef84
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.quicksearchbox.ui; 18 19import com.android.quicksearchbox.Corpus; 20import com.android.quicksearchbox.Promoter; 21import com.android.quicksearchbox.R; 22import com.android.quicksearchbox.Suggestions; 23 24import android.animation.ObjectAnimator; 25import android.animation.ValueAnimator; 26import android.animation.ValueAnimator.AnimatorUpdateListener; 27import android.content.Context; 28import android.database.DataSetObserver; 29import android.graphics.drawable.Drawable; 30import android.util.AttributeSet; 31import android.util.Log; 32import android.view.Menu; 33import android.view.MenuItem; 34import android.view.View; 35import android.widget.ExpandableListAdapter; 36import android.widget.ImageView; 37import android.widget.PopupMenu; 38 39/** 40 * Two-pane variant for the search activity view. 41 */ 42public class SearchActivityViewTwoPane extends SearchActivityView { 43 44 private static final int TINT_ANIMATION_DURATION = 300; // in millis 45 private static final int TINT_ANIMATION_START_DELAY = 400; // in millis 46 47 private ImageView mMenuButton; 48 49 // View that shows the results other than the query completions 50 private ClusteredSuggestionsView mResultsView; 51 private SuggestionsAdapter<ExpandableListAdapter> mResultsAdapter; 52 private View mResultsHeader; 53 54 public SearchActivityViewTwoPane(Context context) { 55 super(context); 56 } 57 58 public SearchActivityViewTwoPane(Context context, AttributeSet attrs) { 59 super(context, attrs); 60 } 61 62 public SearchActivityViewTwoPane(Context context, AttributeSet attrs, int defStyle) { 63 super(context, attrs, defStyle); 64 } 65 66 @Override 67 protected void onFinishInflate() { 68 super.onFinishInflate(); 69 70 mMenuButton = (ImageView) findViewById(R.id.menu_button); 71 mMenuButton.setOnClickListener(new View.OnClickListener() { 72 public void onClick(View v) { 73 showPopupMenu(); 74 } 75 }); 76 77 mResultsView = (ClusteredSuggestionsView) findViewById(R.id.shortcuts); 78 mResultsAdapter = createClusteredSuggestionsAdapter(); 79 mResultsAdapter.setSuggestionAdapterChangeListener(this); 80 mResultsAdapter.getListAdapter().registerDataSetObserver(new DataSetObserver(){ 81 @Override 82 public void onChanged() { 83 mResultsView.expandAll(); 84 } 85 }); 86 mResultsView.setOnKeyListener(new SuggestionsViewKeyListener()); 87 mResultsHeader = findViewById(R.id.shortcut_title); 88 89 mSuggestionsAdapter.setIcon1Enabled(false); 90 } 91 92 private void showPopupMenu() { 93 PopupMenu popup = new PopupMenu(getContext(), mMenuButton); 94 Menu menu = popup.getMenu(); 95 getActivity().createMenuItems(menu, false); 96 popup.show(); 97 } 98 99 protected SuggestionsAdapter<ExpandableListAdapter> createClusteredSuggestionsAdapter() { 100 return new DelayingSuggestionsAdapter<ExpandableListAdapter>( 101 new ClusteredSuggestionsAdapter( 102 getQsbApplication().getDefaultSuggestionViewFactory(), 103 getQsbApplication().getCorpora(), getContext())); 104 } 105 106 @Override 107 public void onSuggestionAdapterChanged() { 108 mResultsView.setSuggestionsAdapter(mResultsAdapter); 109 super.onSuggestionAdapterChanged(); 110 } 111 112 @Override 113 public void onResume() { 114 setupWallpaperTint(); 115 } 116 117 private void setupWallpaperTint() { 118 // Alpha fade-in the background tint when the activity resumes. 119 final Drawable drawable = getBackground(); 120 drawable.setAlpha(0); 121 ValueAnimator animator = ObjectAnimator.ofInt(drawable, "alpha", 0, 255); 122 animator.setDuration(TINT_ANIMATION_DURATION); 123 animator.addUpdateListener(new AnimatorUpdateListener() { 124 125 public void onAnimationUpdate(ValueAnimator animator) { 126 drawable.invalidateSelf(); 127 } 128 }); 129 animator.setStartDelay(TINT_ANIMATION_START_DELAY); 130 animator.setInterpolator(new android.view.animation.LinearInterpolator()); 131 animator.start(); 132 } 133 134 @Override 135 public void onStop() { 136 } 137 138 @Override 139 public void start() { 140 super.start(); 141 mResultsAdapter.getListAdapter().registerDataSetObserver(new ResultsObserver()); 142 mResultsView.setSuggestionsAdapter(mResultsAdapter); 143 } 144 145 @Override 146 public void destroy() { 147 mResultsAdapter.setSuggestionAdapterChangeListener(null); 148 mResultsView.setSuggestionsAdapter(null); 149 150 super.destroy(); 151 } 152 153 @Override 154 public void considerHidingInputMethod() { 155 // Don't hide keyboard when interacting with suggestions list 156 } 157 158 @Override 159 public void hideSuggestions() { 160 // Never hiding suggestions view in two-pane UI 161 } 162 163 @Override 164 public void showSuggestions() { 165 // Never hiding suggestions view in two-pane UI 166 } 167 168 @Override 169 public void showCorpusSelectionDialog() { 170 // not used 171 } 172 173 @Override 174 public void clearSuggestions() { 175 super.clearSuggestions(); 176 mResultsAdapter.setSuggestions(null); 177 } 178 179 @Override 180 public void setMaxPromotedResults(int maxPromoted) { 181 mResultsView.setLimitSuggestionsToViewHeight(false); 182 mResultsAdapter.setMaxPromoted(maxPromoted); 183 } 184 185 @Override 186 public void limitResultsToViewHeight() { 187 mResultsView.setLimitSuggestionsToViewHeight(true); 188 } 189 190 @Override 191 public void setSuggestionClickListener(SuggestionClickListener listener) { 192 super.setSuggestionClickListener(listener); 193 mResultsAdapter.setSuggestionClickListener(listener); 194 } 195 196 @Override 197 public void setEmptySpaceClickListener(final View.OnClickListener listener) { 198 findViewById(R.id.panes).setOnClickListener(listener); 199 } 200 201 @Override 202 public void setSuggestions(Suggestions suggestions) { 203 super.setSuggestions(suggestions); 204 suggestions.acquire(); 205 mResultsAdapter.setSuggestions(suggestions); 206 } 207 208 @Override 209 protected void setCorpus(Corpus corpus) { 210 super.setCorpus(corpus); 211 mResultsAdapter.setPromoter(createResultsPromoter()); 212 } 213 214 @Override 215 protected Promoter createSuggestionsPromoter() { 216 return getQsbApplication().createWebPromoter(); 217 } 218 219 protected Promoter createResultsPromoter() { 220 Corpus corpus = getCorpus(); 221 if (corpus == null) { 222 return getQsbApplication().createResultsPromoter(); 223 } else { 224 return getQsbApplication().createSingleCorpusResultsPromoter(corpus); 225 } 226 } 227 228 protected void onResultsChanged() { 229 checkHideResultsHeader(); 230 } 231 232 private void checkHideResultsHeader() { 233 if (mResultsHeader != null) { 234 if (!mResultsAdapter.isEmpty()) { 235 if (DBG) Log.d(TAG, "Results non-empty"); 236 mResultsHeader.setVisibility(VISIBLE); 237 } else { 238 if (DBG) Log.d(TAG, "Results empty"); 239 mResultsHeader.setVisibility(INVISIBLE); 240 } 241 } 242 } 243 244 @Override 245 public Corpus getSearchCorpus() { 246 return getWebCorpus(); 247 } 248 249 protected class ResultsObserver extends DataSetObserver { 250 @Override 251 public void onChanged() { 252 onResultsChanged(); 253 } 254 } 255 256} 257