Files
lawnchair/src/com/android/launcher3/ExtendedEditText.java
Andy Wickham 336c6669b0 Remove unnecessary hide keyboard call in onKeyPreIme.
The default handling of back in this preIme case already closes
the keyboard if we return false, so adding it before our own key
handling was stomping on our existing syncronized keyboard.

We should still handle other cases where the system ime animation
coincides with our control, but we at least shouldn't force it on
ourselves.

This fixes the back issue in 3 button mode, and also closes all
apps on the first back gesture as intended (if you hadn't entered
0 state that is).

Demo after fix: https://drive.google.com/file/d/1pK18iEdgxQ0HQmilAMFzn66LVyCH5Ma1/view?usp=drive_link&resourcekey=0-kW4BOC-Pj-wZ_DZL51z6Rg

Bug: 270144901
Bug: 277738379
Test: Manual with 3 button mode and gesture nav, with always on
keyboard on and off
Flag: N/A

Change-Id: I9b1c525494b49cde3307df8b0a73d6143ac9c616
2023-08-25 17:26:33 -07:00

184 lines
5.9 KiB
Java

/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3;
import static com.android.launcher3.logging.KeyboardStateManager.KeyboardState.SHOW;
import android.content.Context;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.DragEvent;
import android.view.KeyEvent;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import com.android.launcher3.views.ActivityContext;
import java.util.HashSet;
import java.util.Set;
/**
* The edit text that reports back when the back key has been pressed.
* Note: AppCompatEditText doesn't fully support #displayCompletions and #onCommitCompletion
*/
public class ExtendedEditText extends EditText {
private static final String TAG = "ExtendedEditText";
private final Set<OnFocusChangeListener> mOnFocusChangeListeners = new HashSet<>();
private boolean mForceDisableSuggestions = false;
/**
* Implemented by listeners of the back key.
*/
public interface OnBackKeyListener {
boolean onBackKey();
}
private OnBackKeyListener mBackKeyListener;
public ExtendedEditText(Context context) {
// ctor chaining breaks the touch handling
super(context);
}
public ExtendedEditText(Context context, AttributeSet attrs) {
// ctor chaining breaks the touch handling
super(context, attrs);
}
public ExtendedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setOnBackKeyListener(OnBackKeyListener listener) {
mBackKeyListener = listener;
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
// If this is a back key, propagate the key back to the listener
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP
&& mBackKeyListener != null) {
return mBackKeyListener.onBackKey();
}
return super.onKeyPreIme(keyCode, event);
}
@Override
public boolean onDragEvent(DragEvent event) {
// We don't want this view to interfere with Launcher own drag and drop.
return false;
}
/**
* Synchronously shows the soft input method.
*
* @param shouldFocus whether this EditText should also request focus.
* @return true if the keyboard is shown correctly and focus is given to this view (if
* applicable).
*/
public boolean showKeyboard(boolean shouldFocus) {
onKeyboardShown();
boolean focusResult = !shouldFocus || requestFocus();
return focusResult && showSoftInputInternal();
}
public void hideKeyboard() {
ActivityContext.lookupContext(getContext()).hideKeyboard();
clearFocus();
}
protected void onKeyboardShown() {
ActivityContext.lookupContext(getContext()).getStatsLogManager()
.keyboardStateManager().setKeyboardState(SHOW);
}
private boolean showSoftInputInternal() {
boolean result = false;
InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
if (imm != null) {
result = imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
} else {
Log.w(TAG, "Failed to retrieve InputMethodManager from the system.");
}
return result;
}
public void dispatchBackKey() {
hideKeyboard();
if (mBackKeyListener != null) {
mBackKeyListener.onBackKey();
}
}
/**
* Set to true when you want isSuggestionsEnabled to return false.
* Use this to disable the red underlines that appear under typos when suggestions is enabled.
*/
public void forceDisableSuggestions(boolean forceDisableSuggestions) {
mForceDisableSuggestions = forceDisableSuggestions;
}
@Override
public boolean isSuggestionsEnabled() {
return !mForceDisableSuggestions && super.isSuggestionsEnabled();
}
public void reset() {
if (!TextUtils.isEmpty(getText())) {
setText("");
}
}
/**
* This method should be preferred to {@link #setOnFocusChangeListener(OnFocusChangeListener)},
* as it allows for multiple listeners from different sources.
*/
public void addOnFocusChangeListener(OnFocusChangeListener listener) {
mOnFocusChangeListeners.add(listener);
}
/**
* Removes the given listener from the set of registered focus listeners, or does nothing if it
* wasn't registered in the first place.
*/
public void removeOnFocusChangeListener(OnFocusChangeListener listener) {
mOnFocusChangeListeners.remove(listener);
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
for (OnFocusChangeListener listener : mOnFocusChangeListeners) {
listener.onFocusChange(this, focused);
}
}
/**
* Save the input, suggestion, hint states when it's on focus, and set to unfocused states.
*/
public void saveFocusedStateAndUpdateToUnfocusedState() {}
/**
* Restore to the previous saved focused state.
*/
public void restoreToFocusedState() {}
}