• 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.logging.KeyboardStateManager.KeyboardState.SHOW;
19 
20 import android.content.Context;
21 import android.graphics.Rect;
22 import android.text.TextUtils;
23 import android.util.AttributeSet;
24 import android.util.Log;
25 import android.view.DragEvent;
26 import android.view.KeyEvent;
27 import android.view.inputmethod.InputMethodManager;
28 import android.widget.EditText;
29 
30 import com.android.launcher3.views.ActivityContext;
31 
32 import java.util.HashSet;
33 import java.util.Set;
34 
35 
36 /**
37  * The edit text that reports back when the back key has been pressed.
38  * Note: AppCompatEditText doesn't fully support #displayCompletions and #onCommitCompletion
39  */
40 public class ExtendedEditText extends EditText {
41     private static final String TAG = "ExtendedEditText";
42 
43     private final Set<OnFocusChangeListener> mOnFocusChangeListeners = new HashSet<>();
44 
45     private boolean mForceDisableSuggestions = false;
46 
47     /**
48      * Implemented by listeners of the back key.
49      */
50     public interface OnBackKeyListener {
onBackKey()51         boolean onBackKey();
52     }
53 
54     private OnBackKeyListener mBackKeyListener;
55 
ExtendedEditText(Context context)56     public ExtendedEditText(Context context) {
57         // ctor chaining breaks the touch handling
58         super(context);
59     }
60 
ExtendedEditText(Context context, AttributeSet attrs)61     public ExtendedEditText(Context context, AttributeSet attrs) {
62         // ctor chaining breaks the touch handling
63         super(context, attrs);
64     }
65 
ExtendedEditText(Context context, AttributeSet attrs, int defStyleAttr)66     public ExtendedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
67         super(context, attrs, defStyleAttr);
68     }
69 
setOnBackKeyListener(OnBackKeyListener listener)70     public void setOnBackKeyListener(OnBackKeyListener listener) {
71         mBackKeyListener = listener;
72     }
73 
74     @Override
onKeyPreIme(int keyCode, KeyEvent event)75     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
76         // If this is a back key, propagate the key back to the listener
77         if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP
78                 && mBackKeyListener != null) {
79             return mBackKeyListener.onBackKey();
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     /**
91      * Synchronously shows the soft input method.
92      *
93      * @param shouldFocus whether this EditText should also request focus.
94      * @return true if the keyboard is shown correctly and focus is given to this view (if
95      *     applicable).
96      */
showKeyboard(boolean shouldFocus)97     public boolean showKeyboard(boolean shouldFocus) {
98         onKeyboardShown();
99         boolean focusResult = !shouldFocus || requestFocus();
100         return focusResult && showSoftInputInternal();
101     }
102 
hideKeyboard()103     public void hideKeyboard() {
104         ActivityContext.lookupContext(getContext()).hideKeyboard();
105         clearFocus();
106     }
107 
onKeyboardShown()108     protected void onKeyboardShown() {
109         ActivityContext.lookupContext(getContext()).getStatsLogManager()
110                 .keyboardStateManager().setKeyboardState(SHOW);
111     }
112 
showSoftInputInternal()113     private boolean showSoftInputInternal() {
114         boolean result = false;
115         InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
116         if (imm != null) {
117             result = imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
118         } else {
119             Log.w(TAG, "Failed to retrieve InputMethodManager from the system.");
120         }
121         return result;
122     }
123 
dispatchBackKey()124     public void dispatchBackKey() {
125         hideKeyboard();
126         if (mBackKeyListener != null) {
127             mBackKeyListener.onBackKey();
128         }
129     }
130 
131     /**
132      * Set to true when you want isSuggestionsEnabled to return false.
133      * Use this to disable the red underlines that appear under typos when suggestions is enabled.
134      */
forceDisableSuggestions(boolean forceDisableSuggestions)135     public void forceDisableSuggestions(boolean forceDisableSuggestions) {
136         mForceDisableSuggestions = forceDisableSuggestions;
137     }
138 
139     @Override
isSuggestionsEnabled()140     public boolean isSuggestionsEnabled() {
141         return !mForceDisableSuggestions && super.isSuggestionsEnabled();
142     }
143 
reset()144     public void reset() {
145         if (!TextUtils.isEmpty(getText())) {
146             setText("");
147         }
148     }
149 
150     /**
151      * This method should be preferred to {@link #setOnFocusChangeListener(OnFocusChangeListener)},
152      * as it allows for multiple listeners from different sources.
153      */
addOnFocusChangeListener(OnFocusChangeListener listener)154     public void addOnFocusChangeListener(OnFocusChangeListener listener) {
155         mOnFocusChangeListeners.add(listener);
156     }
157 
158     /**
159      * Removes the given listener from the set of registered focus listeners, or does nothing if it
160      * wasn't registered in the first place.
161      */
removeOnFocusChangeListener(OnFocusChangeListener listener)162     public void removeOnFocusChangeListener(OnFocusChangeListener listener) {
163         mOnFocusChangeListeners.remove(listener);
164     }
165 
166     @Override
onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect)167     protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
168         super.onFocusChanged(focused, direction, previouslyFocusedRect);
169         for (OnFocusChangeListener listener : mOnFocusChangeListeners) {
170             listener.onFocusChange(this, focused);
171         }
172     }
173 
174     /**
175      * Save the input, suggestion, hint states when it's on focus, and set to unfocused states.
176      */
saveFocusedStateAndUpdateToUnfocusedState()177     public void saveFocusedStateAndUpdateToUnfocusedState() {}
178 
179     /**
180      * Restore to the previous saved focused state.
181      */
restoreToFocusedState()182     public void restoreToFocusedState() {}
183 }
184