AllAppsSearchBarController.java revision 9e3fee1427c0baa38564e20a9f351d1a87c25761
1/* 2 * Copyright (C) 2015 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 */ 16package com.android.launcher3.allapps; 17 18import android.content.Context; 19import android.graphics.Rect; 20import android.text.Editable; 21import android.text.TextWatcher; 22import android.view.KeyEvent; 23import android.view.View; 24import android.view.ViewGroup; 25import android.view.inputmethod.EditorInfo; 26import android.view.inputmethod.InputMethodManager; 27import android.widget.TextView; 28import android.widget.TextView.OnEditorActionListener; 29 30import com.android.launcher3.ExtendedEditText; 31import com.android.launcher3.Launcher; 32import com.android.launcher3.Utilities; 33import com.android.launcher3.util.ComponentKey; 34 35import java.util.ArrayList; 36 37/** 38 * An interface to a search box that AllApps can command. 39 */ 40public abstract class AllAppsSearchBarController 41 implements TextWatcher, OnEditorActionListener, ExtendedEditText.OnBackKeyListener { 42 43 protected Launcher mLauncher; 44 protected AlphabeticalAppsList mApps; 45 protected Callbacks mCb; 46 protected ExtendedEditText mInput; 47 48 protected DefaultAppSearchAlgorithm mSearchAlgorithm; 49 protected InputMethodManager mInputMethodManager; 50 51 /** 52 * Sets the references to the apps model and the search result callback. 53 */ 54 public final void initialize( 55 AlphabeticalAppsList apps, ExtendedEditText input, 56 Launcher launcher, Callbacks cb) { 57 mApps = apps; 58 mCb = cb; 59 mLauncher = launcher; 60 61 mInput = input; 62 mInput.addTextChangedListener(this); 63 mInput.setOnEditorActionListener(this); 64 mInput.setOnBackKeyListener(this); 65 66 mInputMethodManager = (InputMethodManager) 67 mInput.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 68 69 mSearchAlgorithm = onInitializeSearch(); 70 } 71 72 /** 73 * To be overridden by subclasses. This method will get called when the controller is set. 74 */ 75 protected DefaultAppSearchAlgorithm onInitializeSearch() { 76 return null; 77 } 78 79 @Override 80 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 81 // Do nothing 82 } 83 84 @Override 85 public void onTextChanged(CharSequence s, int start, int before, int count) { 86 // Do nothing 87 } 88 89 @Override 90 public void afterTextChanged(final Editable s) { 91 String query = s.toString(); 92 if (query.isEmpty()) { 93 mSearchAlgorithm.cancel(true); 94 mCb.clearSearchResult(); 95 } else { 96 mSearchAlgorithm.cancel(false); 97 mSearchAlgorithm.doSearch(query, mCb); 98 } 99 } 100 101 @Override 102 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 103 // Skip if it's not the right action 104 if (actionId != EditorInfo.IME_ACTION_SEARCH) { 105 return false; 106 } 107 // Skip if the query is empty 108 String query = v.getText().toString(); 109 if (query.isEmpty()) { 110 return false; 111 } 112 return mLauncher.startActivitySafely( 113 v, AllAppsGridAdapter.createMarketSearchIntent(query), null); 114 } 115 116 @Override 117 public boolean onBackKey() { 118 // Only hide the search field if there is no query, or if there 119 // are no filtered results 120 String query = Utilities.trim(mInput.getEditableText().toString()); 121 if (query.isEmpty() || mApps.hasNoFilteredResults()) { 122 reset(); 123 return true; 124 } 125 return false; 126 } 127 128 /** 129 * Resets the search bar state. 130 */ 131 public void reset() { 132 unfocusSearchField(); 133 mCb.clearSearchResult(); 134 mInput.setText(""); 135 mInputMethodManager.hideSoftInputFromWindow(mInput.getWindowToken(), 0); 136 } 137 138 protected void unfocusSearchField() { 139 View nextFocus = mInput.focusSearch(View.FOCUS_DOWN); 140 if (nextFocus != null) { 141 nextFocus.requestFocus(); 142 } 143 } 144 145 /** 146 * Returns the search bar view. 147 * @param parent the parent to attach the search bar view to. 148 */ 149 public View getView(ViewGroup parent) { 150 return null; 151 } 152 153 /** 154 * Focuses the search field to handle key events. 155 */ 156 public void focusSearchField() { 157 mInput.requestFocus(); 158 mInputMethodManager.showSoftInput(mInput, InputMethodManager.SHOW_IMPLICIT); 159 } 160 161 /** 162 * Returns whether the search field is focused. 163 */ 164 public boolean isSearchFieldFocused() { 165 return mInput.isFocused(); 166 } 167 168 /** 169 * Returns whether the prediction bar should currently be visible depending on the state of 170 * the search bar. 171 */ 172 public boolean shouldShowPredictionBar() { 173 return false; 174 } 175 176 /** 177 * Callback for getting search results. 178 */ 179 public interface Callbacks { 180 181 /** 182 * Called when the bounds of the search bar has changed. 183 */ 184 void onBoundsChanged(Rect newBounds); 185 186 /** 187 * Called when the search is complete. 188 * 189 * @param apps sorted list of matching components or null if in case of failure. 190 */ 191 void onSearchResult(String query, ArrayList<ComponentKey> apps); 192 193 /** 194 * Called when the search results should be cleared. 195 */ 196 void clearSearchResult(); 197 } 198}