1ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung/* 2ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * Copyright (C) 2015 The Android Open Source Project 3ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * 4ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * you may not use this file except in compliance with the License. 6ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * You may obtain a copy of the License at 7ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * 8ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * 10ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * Unless required by applicable law or agreed to in writing, software 11ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * See the License for the specific language governing permissions and 14ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * limitations under the License. 15ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung */ 16ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungpackage com.android.launcher3.allapps; 17ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 18ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.content.Context; 19ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.text.Editable; 20ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.text.TextWatcher; 21ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.view.KeyEvent; 22ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.view.LayoutInflater; 23ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.view.View; 24ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.view.ViewGroup; 25ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.view.inputmethod.EditorInfo; 26ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.view.inputmethod.InputMethodManager; 27ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport android.widget.TextView; 28ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport com.android.launcher3.R; 29ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport com.android.launcher3.Utilities; 30ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport com.android.launcher3.util.Thunk; 31ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 32ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungimport java.util.List; 33ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 344919827990b16ae22595d0b7cb123a875961d9beSunny Goyal 35ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung/** 36ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * The default search controller. 37ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung */ 38ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungfinal class DefaultAppSearchController extends AllAppsSearchBarController 39ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung implements TextWatcher, TextView.OnEditorActionListener, View.OnClickListener { 40ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 41ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private static final boolean ALLOW_SINGLE_APP_LAUNCH = true; 42ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 43ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private static final int FADE_IN_DURATION = 175; 44ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private static final int FADE_OUT_DURATION = 100; 45ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private static final int SEARCH_TRANSLATION_X_DP = 18; 46ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 47ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private final Context mContext; 48ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Thunk final InputMethodManager mInputMethodManager; 49ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 50ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private DefaultAppSearchAlgorithm mSearchManager; 51ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 52ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private ViewGroup mContainerView; 53ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private View mSearchView; 54ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Thunk View mSearchBarContainerView; 55ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private View mSearchButtonView; 56ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private View mDismissSearchButtonView; 57ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Thunk AllAppsSearchEditView mSearchBarEditView; 58ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Thunk AllAppsRecyclerView mAppsRecyclerView; 59383c507c47a5abf3258fc04220f37c366f983a97Sunny Goyal @Thunk Runnable mFocusRecyclerViewRunnable = new Runnable() { 60ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 61ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void run() { 62ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mAppsRecyclerView.requestFocus(); 63ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 64ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung }; 65ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 66ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public DefaultAppSearchController(Context context, ViewGroup containerView, 67ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung AllAppsRecyclerView appsRecyclerView) { 68ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mContext = context; 69ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mInputMethodManager = (InputMethodManager) 70ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 71ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mContainerView = containerView; 72ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mAppsRecyclerView = appsRecyclerView; 73ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 74ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 75ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 76ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public View getView(ViewGroup parent) { 77ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 78ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchView = inflater.inflate(R.layout.all_apps_search_bar, parent, false); 79ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchView.setOnClickListener(this); 80ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 81ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchButtonView = mSearchView.findViewById(R.id.search_button); 82ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarContainerView = mSearchView.findViewById(R.id.search_container); 83ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mDismissSearchButtonView = mSearchBarContainerView.findViewById(R.id.dismiss_search_button); 84ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mDismissSearchButtonView.setOnClickListener(this); 85ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView = (AllAppsSearchEditView) 8601d4053436a6a771b36b527a4f0ff49bbf468632Winson Chung mSearchBarContainerView.findViewById(R.id.search_box_input); 87ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView.addTextChangedListener(this); 88ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView.setOnEditorActionListener(this); 89ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView.setOnBackKeyListener( 90ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung new AllAppsSearchEditView.OnBackKeyListener() { 91ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 92ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void onBackKey() { 93ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only hide the search field if there is no query, or if there 94ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // are no filtered results 95ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung String query = Utilities.trim( 96ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView.getEditableText().toString()); 97ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (query.isEmpty() || mApps.hasNoFilteredResults()) { 98ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung hideSearchField(true, mFocusRecyclerViewRunnable); 99ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 100ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 101ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung }); 102ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung return mSearchView; 103ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 104ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 105ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 106ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void focusSearchField() { 107ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView.requestFocus(); 108ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung showSearchField(); 109ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 110ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 111ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 112ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public boolean isSearchFieldFocused() { 113ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung return mSearchBarEditView.isFocused(); 114ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 115ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 116ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 1174919827990b16ae22595d0b7cb123a875961d9beSunny Goyal protected void onInitialize() { 1184919827990b16ae22595d0b7cb123a875961d9beSunny Goyal mSearchManager = new DefaultAppSearchAlgorithm(mApps.getApps()); 1194919827990b16ae22595d0b7cb123a875961d9beSunny Goyal } 1204919827990b16ae22595d0b7cb123a875961d9beSunny Goyal 1214919827990b16ae22595d0b7cb123a875961d9beSunny Goyal @Override 122ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void reset() { 123ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung hideSearchField(false, null); 124ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 125ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 126ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 127ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public boolean shouldShowPredictionBar() { 1281ae7a5018b48dba562bc18821f0f1e778192ee85Winson Chung return false; 129ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 130ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 131ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 132ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void onClick(View v) { 133ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (v == mSearchView) { 134ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung showSearchField(); 135ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } else if (v == mDismissSearchButtonView) { 136ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung hideSearchField(true, mFocusRecyclerViewRunnable); 137ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 138ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 139ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 140ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 141ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void beforeTextChanged(CharSequence s, int start, int count, int after) { 142ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Do nothing 143ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 144ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 145ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 146ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void onTextChanged(CharSequence s, int start, int before, int count) { 147ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Do nothing 148ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 149ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 150ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 151ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void afterTextChanged(final Editable s) { 152ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung String query = s.toString(); 153ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (query.isEmpty()) { 154ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchManager.cancel(true); 155ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mCb.clearSearchResult(); 156ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } else { 157ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchManager.cancel(false); 158ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchManager.doSearch(query, mCb); 159ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 160ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 161ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 162ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 163ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 164ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Skip if we disallow app-launch-on-enter 165ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (!ALLOW_SINGLE_APP_LAUNCH) { 166ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung return false; 167ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 168ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Skip if it's not the right action 169ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (actionId != EditorInfo.IME_ACTION_DONE) { 170ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung return false; 171ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 172ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Skip if there isn't exactly one item 173ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (mApps.getSize() != 1) { 174ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung return false; 175ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 176ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // If there is exactly one icon, then quick-launch it 177ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems(); 178ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung for (int i = 0; i < items.size(); i++) { 179ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung AlphabeticalAppsList.AdapterItem item = items.get(i); 180ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (item.viewType == AllAppsGridAdapter.ICON_VIEW_TYPE) { 181ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mAppsRecyclerView.getChildAt(i).performClick(); 182ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mInputMethodManager.hideSoftInputFromWindow( 183ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mContainerView.getWindowToken(), 0); 184ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung return true; 185ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 186ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 187ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung return false; 188ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 189ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 190ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung /** 191ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * Focuses the search field. 192ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung */ 193ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private void showSearchField() { 194ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Show the search bar and focus the search 195ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung final int translationX = Utilities.pxFromDp(SEARCH_TRANSLATION_X_DP, 196ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mContext.getResources().getDisplayMetrics()); 197ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarContainerView.setVisibility(View.VISIBLE); 198ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarContainerView.setAlpha(0f); 199ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarContainerView.setTranslationX(translationX); 200ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarContainerView.animate() 201ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .alpha(1f) 202ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .translationX(0) 203ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .setDuration(FADE_IN_DURATION) 204ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .withLayer() 205ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .withEndAction(new Runnable() { 206ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 207ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void run() { 208ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView.requestFocus(); 209ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mInputMethodManager.showSoftInput(mSearchBarEditView, 210ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung InputMethodManager.SHOW_IMPLICIT); 211ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 212ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung }); 213ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchButtonView.animate() 214ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .alpha(0f) 215ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .translationX(-translationX) 216ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .setDuration(FADE_OUT_DURATION) 217ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .withLayer(); 218ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 219ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 220ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung /** 221ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * Unfocuses the search field. 222ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung */ 223ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Thunk void hideSearchField(boolean animated, final Runnable postAnimationRunnable) { 224ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchManager.cancel(true); 225ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 226ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung final boolean resetTextField = mSearchBarEditView.getText().toString().length() > 0; 227ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung final int translationX = Utilities.pxFromDp(SEARCH_TRANSLATION_X_DP, 228ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mContext.getResources().getDisplayMetrics()); 229ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (animated) { 230ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Hide the search bar and focus the recycler view 231ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarContainerView.animate() 232ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .alpha(0f) 233ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .translationX(0) 234ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .setDuration(FADE_IN_DURATION) 235ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .withLayer() 236ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .withEndAction(new Runnable() { 237ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung @Override 238ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void run() { 239ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarContainerView.setVisibility(View.INVISIBLE); 240ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (resetTextField) { 241ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView.setText(""); 242ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 243ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mCb.clearSearchResult(); 244ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (postAnimationRunnable != null) { 245ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung postAnimationRunnable.run(); 246ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 247ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 248ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung }); 249ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchButtonView.setTranslationX(-translationX); 250ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchButtonView.animate() 251ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .alpha(1f) 252ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .translationX(0) 253ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .setDuration(FADE_OUT_DURATION) 254ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung .withLayer(); 255ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } else { 256ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarContainerView.setVisibility(View.INVISIBLE); 257ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (resetTextField) { 258ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchBarEditView.setText(""); 259ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 260ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mCb.clearSearchResult(); 261ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchButtonView.setAlpha(1f); 262ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mSearchButtonView.setTranslationX(0f); 263ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (postAnimationRunnable != null) { 264ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung postAnimationRunnable.run(); 265ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 266ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 267ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mInputMethodManager.hideSoftInputFromWindow(mContainerView.getWindowToken(), 0); 268ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 269ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung} 270