• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
16 package com.android.launcher3;
17 
18 import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
19 
20 import android.content.Context;
21 import android.text.TextUtils;
22 import android.util.AttributeSet;
23 import android.view.DragEvent;
24 import android.view.KeyEvent;
25 import android.view.View;
26 import android.view.inputmethod.InputMethodManager;
27 import android.widget.EditText;
28 
29 import com.android.launcher3.config.FeatureFlags;
30 import com.android.launcher3.views.ActivityContext;
31 
32 
33 /**
34  * The edit text that reports back when the back key has been pressed.
35  * Note: AppCompatEditText doesn't fully support #displayCompletions and #onCommitCompletion
36  */
37 public class ExtendedEditText extends EditText {
38 
39     private boolean mShowImeAfterFirstLayout;
40     private boolean mForceDisableSuggestions = false;
41 
42     /**
43      * Implemented by listeners of the back key.
44      */
45     public interface OnBackKeyListener {
onBackKey()46         boolean onBackKey();
47     }
48 
49     private OnBackKeyListener mBackKeyListener;
50 
ExtendedEditText(Context context)51     public ExtendedEditText(Context context) {
52         // ctor chaining breaks the touch handling
53         super(context);
54     }
55 
ExtendedEditText(Context context, AttributeSet attrs)56     public ExtendedEditText(Context context, AttributeSet attrs) {
57         // ctor chaining breaks the touch handling
58         super(context, attrs);
59     }
60 
ExtendedEditText(Context context, AttributeSet attrs, int defStyleAttr)61     public ExtendedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
62         super(context, attrs, defStyleAttr);
63     }
64 
setOnBackKeyListener(OnBackKeyListener listener)65     public void setOnBackKeyListener(OnBackKeyListener listener) {
66         mBackKeyListener = listener;
67     }
68 
69     @Override
onKeyPreIme(int keyCode, KeyEvent event)70     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
71         // If this is a back key, propagate the key back to the listener
72         if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
73             if (TextUtils.isEmpty(getText())) {
74                 hideKeyboard();
75             }
76             if (mBackKeyListener != null) {
77                 return mBackKeyListener.onBackKey();
78             }
79             return false;
80         }
81         return super.onKeyPreIme(keyCode, event);
82     }
83 
84     @Override
onDragEvent(DragEvent event)85     public boolean onDragEvent(DragEvent event) {
86         // We don't want this view to interfere with Launcher own drag and drop.
87         return false;
88     }
89 
90     @Override
onLayout(boolean changed, int left, int top, int right, int bottom)91     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
92         super.onLayout(changed, left, top, right, bottom);
93         if (mShowImeAfterFirstLayout) {
94             // soft input only shows one frame after the layout of the EditText happens,
95             post(() -> {
96                 showSoftInput();
97                 mShowImeAfterFirstLayout = false;
98             });
99         }
100     }
101 
102     // inherited class can override to change the appearance of the edit text.
show()103     public void show() {}
104 
showKeyboard()105     public void showKeyboard() {
106         mShowImeAfterFirstLayout = !showSoftInput();
107     }
108 
hideKeyboard()109     public void hideKeyboard() {
110         hideKeyboardAsync(ActivityContext.lookupContext(getContext()), getWindowToken());
111     }
112 
showSoftInput()113     private boolean showSoftInput() {
114         return requestFocus() &&
115                 getContext().getSystemService(InputMethodManager.class)
116                     .showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
117     }
118 
dispatchBackKey()119     public void dispatchBackKey() {
120         hideKeyboard();
121         if (mBackKeyListener != null) {
122             mBackKeyListener.onBackKey();
123         }
124     }
125 
126     /**
127      * Set to true when you want isSuggestionsEnabled to return false.
128      * Use this to disable the red underlines that appear under typos when suggestions is enabled.
129      */
forceDisableSuggestions(boolean forceDisableSuggestions)130     public void forceDisableSuggestions(boolean forceDisableSuggestions) {
131         mForceDisableSuggestions = forceDisableSuggestions;
132     }
133 
134     @Override
isSuggestionsEnabled()135     public boolean isSuggestionsEnabled() {
136         return !mForceDisableSuggestions && super.isSuggestionsEnabled();
137     }
138 
reset()139     public void reset() {
140         if (!TextUtils.isEmpty(getText())) {
141             setText("");
142         }
143         if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
144             return;
145         }
146         if (isFocused()) {
147             View nextFocus = focusSearch(View.FOCUS_DOWN);
148             if (nextFocus != null) {
149                 nextFocus.requestFocus();
150             }
151         }
152         hideKeyboard();
153     }
154 }
155