1 /* 2 * Copyright (C) 2021 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 17 package com.android.launcher3.widget.picker.search; 18 19 import static android.view.View.GONE; 20 import static android.view.View.VISIBLE; 21 22 import android.text.Editable; 23 import android.text.TextWatcher; 24 import android.util.Log; 25 import android.view.KeyEvent; 26 import android.view.View; 27 import android.widget.ImageButton; 28 29 import com.android.launcher3.ExtendedEditText; 30 import com.android.launcher3.search.SearchAlgorithm; 31 import com.android.launcher3.search.SearchCallback; 32 import com.android.launcher3.widget.model.WidgetsListBaseEntry; 33 34 import java.util.ArrayList; 35 36 /** 37 * Controller for a search bar with an edit text and a cancel button. 38 */ 39 public class WidgetsSearchBarController implements TextWatcher, 40 SearchCallback<WidgetsListBaseEntry>, ExtendedEditText.OnBackKeyListener, 41 View.OnKeyListener { 42 private static final String TAG = "WidgetsSearchBarController"; 43 private static final boolean DEBUG = false; 44 45 protected SearchAlgorithm<WidgetsListBaseEntry> mSearchAlgorithm; 46 protected ExtendedEditText mInput; 47 protected ImageButton mCancelButton; 48 protected SearchModeListener mSearchModeListener; 49 protected String mQuery; 50 WidgetsSearchBarController( SearchAlgorithm<WidgetsListBaseEntry> algo, ExtendedEditText editText, ImageButton cancelButton, SearchModeListener searchModeListener)51 public WidgetsSearchBarController( 52 SearchAlgorithm<WidgetsListBaseEntry> algo, ExtendedEditText editText, 53 ImageButton cancelButton, SearchModeListener searchModeListener) { 54 mSearchAlgorithm = algo; 55 mInput = editText; 56 mInput.addTextChangedListener(this); 57 mInput.setOnBackKeyListener(this); 58 mInput.setOnKeyListener(this); 59 mCancelButton = cancelButton; 60 mCancelButton.setOnClickListener(v -> clearSearchResult()); 61 mSearchModeListener = searchModeListener; 62 } 63 64 @Override afterTextChanged(final Editable s)65 public void afterTextChanged(final Editable s) { 66 mQuery = s.toString(); 67 if (mQuery.isEmpty()) { 68 mSearchAlgorithm.cancel(/* interruptActiveRequests= */ true); 69 mSearchModeListener.exitSearchMode(); 70 mCancelButton.setVisibility(GONE); 71 } else { 72 mSearchAlgorithm.cancel(/* interruptActiveRequests= */ false); 73 mSearchModeListener.enterSearchMode(); 74 mSearchAlgorithm.doSearch(mQuery, this); 75 mCancelButton.setVisibility(VISIBLE); 76 } 77 } 78 79 @Override beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)80 public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 81 // Do nothing. 82 } 83 84 @Override onTextChanged(CharSequence charSequence, int i, int i1, int i2)85 public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 86 // Do nothing. 87 } 88 89 @Override onSearchResult(String query, ArrayList<WidgetsListBaseEntry> items)90 public void onSearchResult(String query, ArrayList<WidgetsListBaseEntry> items) { 91 if (DEBUG) { 92 Log.d(TAG, "onSearchResult query: " + query + " items: " + items); 93 } 94 mSearchModeListener.onSearchResults(items); 95 } 96 97 @Override onAppendSearchResult(String query, ArrayList<WidgetsListBaseEntry> items)98 public void onAppendSearchResult(String query, ArrayList<WidgetsListBaseEntry> items) { 99 // Not needed. 100 } 101 102 @Override clearSearchResult()103 public void clearSearchResult() { 104 // Any existing search session will be cancelled by setting text to empty. 105 mInput.setText(""); 106 } 107 108 /** 109 * Cleans up after search is no longer needed. 110 */ onDestroy()111 public void onDestroy() { 112 mSearchAlgorithm.destroy(); 113 } 114 115 @Override onBackKey()116 public boolean onBackKey() { 117 clearFocus(); 118 return true; 119 } 120 121 @Override onKey(View view, int keyCode, KeyEvent event)122 public boolean onKey(View view, int keyCode, KeyEvent event) { 123 if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) { 124 clearFocus(); 125 return true; 126 } 127 return false; 128 } 129 130 /** 131 * Clears focus from edit text. 132 */ clearFocus()133 public void clearFocus() { 134 mInput.clearFocus(); 135 mInput.hideKeyboard(); 136 } 137 } 138