SearchActivityViewTwoPane.java revision f95d552f5a4d8b61219f4c06ce6698ed2a5f0e10
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 PopupMenu popup = new PopupMenu(getContext(), mMenuButton); 74 Menu menu = popup.getMenu(); 75 getActivity().onCreateOptionsMenu(menu); 76 getActivity().onPrepareOptionsMenu(menu); 77 popup.show(); 78 } 79 }); 80 81 mResultsView = (ClusteredSuggestionsView) findViewById(R.id.shortcuts); 82 mResultsAdapter = createClusteredSuggestionsAdapter(); 83 mResultsAdapter.setSuggestionAdapterChangeListener(this); 84 mResultsAdapter.getListAdapter().registerDataSetObserver(new DataSetObserver(){ 85 @Override 86 public void onChanged() { 87 mResultsView.expandAll(); 88 } 89 }); 90 mResultsView.setOnKeyListener(new SuggestionsViewKeyListener()); 91 mResultsHeader = findViewById(R.id.shortcut_title); 92 93 mSuggestionsAdapter.setIcon1Enabled(false); 94 } 95 96 protected SuggestionsAdapter<ExpandableListAdapter> createClusteredSuggestionsAdapter() { 97 return new DelayingSuggestionsAdapter<ExpandableListAdapter>( 98 new ClusteredSuggestionsAdapter( 99 getQsbApplication().getDefaultSuggestionViewFactory(), 100 getQsbApplication().getCorpora(), getContext())); 101 } 102 103 @Override 104 public void onSuggestionAdapterChanged() { 105 mResultsView.setSuggestionsAdapter(mResultsAdapter); 106 super.onSuggestionAdapterChanged(); 107 } 108 109 @Override 110 public void onResume() { 111 setupWallpaperTint(); 112 } 113 114 private void setupWallpaperTint() { 115 // Alpha fade-in the background tint when the activity resumes. 116 final Drawable drawable = getBackground(); 117 drawable.setAlpha(0); 118 ValueAnimator animator = ObjectAnimator.ofInt(drawable, "alpha", 0, 255); 119 animator.setDuration(TINT_ANIMATION_DURATION); 120 animator.addUpdateListener(new AnimatorUpdateListener() { 121 122 public void onAnimationUpdate(ValueAnimator animator) { 123 drawable.invalidateSelf(); 124 } 125 }); 126 animator.setStartDelay(TINT_ANIMATION_START_DELAY); 127 animator.setInterpolator(new android.view.animation.LinearInterpolator()); 128 animator.start(); 129 } 130 131 @Override 132 public void onStop() { 133 } 134 135 @Override 136 public void start() { 137 super.start(); 138 mResultsAdapter.getListAdapter().registerDataSetObserver(new ResultsObserver()); 139 mResultsView.setSuggestionsAdapter(mResultsAdapter); 140 } 141 142 @Override 143 public void destroy() { 144 mResultsAdapter.setSuggestionAdapterChangeListener(null); 145 mResultsView.setSuggestionsAdapter(null); 146 147 super.destroy(); 148 } 149 150 @Override 151 public void considerHidingInputMethod() { 152 // Don't hide keyboard when interacting with suggestions list 153 } 154 155 @Override 156 public void hideSuggestions() { 157 // Never hiding suggestions view in two-pane UI 158 } 159 160 @Override 161 public void showSuggestions() { 162 // Never hiding suggestions view in two-pane UI 163 } 164 165 @Override 166 public void showCorpusSelectionDialog() { 167 // not used 168 } 169 170 @Override 171 public void clearSuggestions() { 172 super.clearSuggestions(); 173 mResultsAdapter.setSuggestions(null); 174 } 175 176 @Override 177 public void setMaxPromotedResults(int maxPromoted) { 178 mResultsView.setLimitSuggestionsToViewHeight(false); 179 mResultsAdapter.setMaxPromoted(maxPromoted); 180 } 181 182 @Override 183 public void limitResultsToViewHeight() { 184 mResultsView.setLimitSuggestionsToViewHeight(true); 185 } 186 187 @Override 188 public void setSuggestionClickListener(SuggestionClickListener listener) { 189 super.setSuggestionClickListener(listener); 190 mResultsAdapter.setSuggestionClickListener(listener); 191 } 192 193 @Override 194 public void setEmptySpaceClickListener(final View.OnClickListener listener) { 195 findViewById(R.id.panes).setOnClickListener(listener); 196 } 197 198 @Override 199 public void setSuggestions(Suggestions suggestions) { 200 super.setSuggestions(suggestions); 201 suggestions.acquire(); 202 mResultsAdapter.setSuggestions(suggestions); 203 } 204 205 @Override 206 protected void setCorpus(Corpus corpus) { 207 super.setCorpus(corpus); 208 mResultsAdapter.setPromoter(createResultsPromoter()); 209 } 210 211 @Override 212 protected Promoter createSuggestionsPromoter() { 213 return getQsbApplication().createWebPromoter(); 214 } 215 216 protected Promoter createResultsPromoter() { 217 Corpus corpus = getCorpus(); 218 if (corpus == null) { 219 return getQsbApplication().createResultsPromoter(); 220 } else { 221 return getQsbApplication().createSingleCorpusResultsPromoter(corpus); 222 } 223 } 224 225 protected void onResultsChanged() { 226 checkHideResultsHeader(); 227 } 228 229 private void checkHideResultsHeader() { 230 if (mResultsHeader != null) { 231 if (!mResultsAdapter.isEmpty()) { 232 if (DBG) Log.d(TAG, "Results non-empty"); 233 mResultsHeader.setVisibility(VISIBLE); 234 } else { 235 if (DBG) Log.d(TAG, "Results empty"); 236 mResultsHeader.setVisibility(INVISIBLE); 237 } 238 } 239 } 240 241 @Override 242 public Corpus getSearchCorpus() { 243 return getWebCorpus(); 244 } 245 246 protected class ResultsObserver extends DataSetObserver { 247 @Override 248 public void onChanged() { 249 onResultsChanged(); 250 } 251 } 252 253} 254