问题
When I move the cursor in a EditText widget the soft keyboard is unresponsive for a couple of seconds.
I have cold booted the device, and tried a different keyboard but the problem remains in just one EditText widget. This problem does not happen on a tablet or in the emulator just on this Samsung Galaxy S7.
It also does not happen for the same EditText widget when I rotate the device to landscape, where the softkeyboard covers the screen with it's own attached edit window. Which suggests the problem is internal to the EditText widget but that's ridiculous.
Everywhere else in the app, the keyboard works fine, including in the EditText widgets inside an AlertDialg and a EditTextPreference.
I have no animations or timers, so nothing that I can see which could be blocking the UI thread, but like I said it only happens if I move the cursor inside the EditText widget.
I can't easily display the code here as it has a lot of sensitive functionality in the activity which would be impossible to obfuscate just for display on SO.
This is LogCat starting with me moving the cursor then repeatedly pressing the Done action to close the keyboard.
D/ViewRootImpl@3513940[MainActivity]: ViewPostIme pointer 0
D/ViewRootImpl@3513940[MainActivity]: ViewPostIme pointer 1
D/InputMethodManager: SSI - flag : 0 Pid : 9760 view : org.pep.dungle
D/ViewRootImpl@92caa69[PopupWindow:541b8a2]: setView = android.widget.PopupWindow$PopupDecorView{a26bcee VFE...C.. ......I. 0,0-0,0} TM=true MM=false
D/ViewRootImpl@92caa69[PopupWindow:541b8a2]: dispatchAttachedToWindow
V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0
D/ViewRootImpl@92caa69[PopupWindow:541b8a2]: Relayout returned: old=[0,0][0,0] new=[378,969][1458,2889] result=0x7 surface={valid=true 543940485120} changed=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000, [1080x1920]-format:1
D/OpenGLRenderer: eglCreateWindowSurface = 0x7ed5e10080
D/ViewRootImpl@92caa69[PopupWindow:541b8a2]: MSG_RESIZED_REPORT: frame=Rect(378, 969 - 1458, 2889) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/OpenGLRenderer: eglDestroySurface = 0x7ed5e10080
D/ViewRootImpl@92caa69[PopupWindow:541b8a2]: dispatchDetachedFromWindow
D/InputEventReceiver: channel '69e6cbf PopupWindow:541b8a2 (client)' ~ Disposing input event receiver.
D/InputEventReceiver: channel '69e6cbf PopupWindow:541b8a2 (client)' ~NativeInputEventReceiver.
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: setView = android.widget.PopupWindow$PopupDecorView{289c208 VFE...C.. ......I. 0,0-0,0} TM=true MM=false
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: dispatchAttachedToWindow
V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: Relayout returned: old=[0,0][0,0] new=[378,1035][1458,2955] result=0x7 surface={valid=true 543940485120} changed=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000, [1080x1920]-format:1
D/OpenGLRenderer: eglCreateWindowSurface = 0x7ed5e10080
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: MSG_RESIZED_REPORT: frame=Rect(378, 1035 - 1458, 2955) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 0
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: ViewPostIme pointer 1
D/OpenGLRenderer: eglDestroySurface = 0x7ed5e10080
D/ViewRootImpl@9b68bab[PopupWindow:541b8a2]: dispatchDetachedFromWindow
D/InputEventReceiver: channel '71f96d5 PopupWindow:541b8a2 (client)' ~ Disposing input event receiver.
channel '71f96d5 PopupWindow:541b8a2 (client)' ~NativeInputEventReceiver.
D/InputMethodManager: HSIFW - flag : 0 Pid : 9760
D/ViewRootImpl@3513940[MainActivity]: MSG_RESIZED: frame=Rect(0, 0 - 1080, 1920) ci=Rect(0, 72 - 0, 0) vi=Rect(0, 72 - 0, 0) or=1
And this is LogCat when I move the cursor then wait for the Disposing input event receiver event, after which the first press of the Done action closes the keyboard. Though I'm not sure if that is because the input event receiver was disposed off, or because I waited a couple of seconds before pressing the Done action.
D/ViewRootImpl@3513940[MainActivity]: ViewPostIme pointer 0
D/ViewRootImpl@3513940[MainActivity]: ViewPostIme pointer 1
D/InputMethodManager: SSI - flag : 0 Pid : 9760 view : org.pep.dungle
D/ViewRootImpl@f9bed82[PopupWindow:efec7f7]: setView = android.widget.PopupWindow$PopupDecorView{7f4b4d0 VFE...C.. ......I. 0,0-0,0} TM=true MM=false
D/ViewRootImpl@f9bed82[PopupWindow:efec7f7]: dispatchAttachedToWindow
V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0
D/ViewRootImpl@f9bed82[PopupWindow:efec7f7]: Relayout returned: old=[0,0][0,0] new=[378,969][1458,2889] result=0x7 surface={valid=true 543931449344} changed=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000, [1080x1920]-format:1
D/OpenGLRenderer: eglCreateWindowSurface = 0x7ee0a40710
D/ViewRootImpl@f9bed82[PopupWindow:efec7f7]: MSG_RESIZED_REPORT: frame=Rect(378, 969 - 1458, 2889) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/OpenGLRenderer: eglDestroySurface = 0x7ee0a40710
D/ViewRootImpl@f9bed82[PopupWindow:efec7f7]: dispatchDetachedFromWindow
D/InputEventReceiver: channel '78a5217 PopupWindow:efec7f7 (client)' ~ Disposing input event receiver.
channel '78a5217 PopupWindow:efec7f7 (client)' ~NativeInputEventReceiver.
D/ViewRootImpl@ca42c85[PopupWindow:efec7f7]: setView = android.widget.PopupWindow$PopupDecorView{b55aada VFE...C.. ......I. 0,0-0,0} TM=true MM=false
D/ViewRootImpl@ca42c85[PopupWindow:efec7f7]: dispatchAttachedToWindow
V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0
D/ViewRootImpl@ca42c85[PopupWindow:efec7f7]: Relayout returned: old=[0,0][0,0] new=[378,1035][1458,2955] result=0x7 surface={valid=true 543931449344} changed=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000, [1080x1920]-format:1
D/OpenGLRenderer: eglCreateWindowSurface = 0x7ed5fbc180
D/ViewRootImpl@ca42c85[PopupWindow:efec7f7]: MSG_RESIZED_REPORT: frame=Rect(378, 1035 - 1458, 2955) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/OpenGLRenderer: eglDestroySurface = 0x7ed5fbc180
D/ViewRootImpl@ca42c85[PopupWindow:efec7f7]: dispatchDetachedFromWindow
D/InputEventReceiver: channel '18797ed PopupWindow:efec7f7 (client)' ~ Disposing input event receiver.
channel '18797ed PopupWindow:efec7f7 (client)' ~NativeInputEventReceiver.
D/InputMethodManager: HSIFW - flag : 0 Pid : 9760
D/ViewRootImpl@3513940[MainActivity]: MSG_RESIZED: frame=Rect(0, 0 - 1080, 1920) ci=Rect(0, 72 - 0, 0) vi=Rect(0, 72 - 0, 0) or=1
As the problem does not occur on other devices or anywhere else in the app, I'm confused as to where to look for the problem.
EDIT
The layout for the EditText widget.
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="@android:color/transparent"
android:hint="@string/hint"
android:imeOptions="actionDone"
android:inputType="text"
android:singleLine="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bottom_guideline" />
Handling code in fragment.
EditText editText = view.findViewById(R.id.editText);
editText.setOnEditorActionListener((textView, actionId, event) ->
{
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE)
{
// Save value.
valueOfEditText = textView.getText().toString();
// Shutdown the keyboard.
InputMethodManager imm = (InputMethodManager) textView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
//noinspection ConstantConditions
imm.hideSoftInputFromWindow(textView.getWindowToken(), 0);
// Signal that we handled the input so any other listeners higher up will ignore it.
handled = true;
}
return handled;
});
UPDATE Now without any changes to the code, the problem is happening even if I open the EditText and do nothing at all. I am now having to wait a couple of seconds to click the backspace key after I enter the EditText field.
As always I am having to wait for dispatchDetachedFromWindow to be called before I can make any changes to the text or click the Done action button. And I can't call that method directly in some listener because it is part of ViewRootImpl.
I'm starting to wonder if this is something local to this phone, rather than all S7 devices.
UPDATE A device reset solved whatever issue was causing this to happen. So it was a local issue on the device, nothing code related.
回答1:
I got the same problem as you. As you said, it just happens on Samsung device.
I set some texts in the Editview in the onCreate and the cursor initially appears at the start of the text when the layout is shown. Then if we move the cursor to the end of the text and type back button immediately, the keyboard will lose response for several seconds. While it is working if you type another button rather than back button.
The possible affected case is users want to delete the existing text, so they type the back button. This issue makes them feel they have to type the back button multiple times to start deleting the text.
The possible solution is setting the cursor at the end of the text when initializing the EditView, something like:
mUsernameEditView.setSelection(username.length());
I understand it is not perfect, but have other ideas.
Update
The real reason is I override android:textSelectHandle, android:textSelectHandleLeft and android:textSelectHandleRight in the AppTheme like below:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:textSelectHandle">@android:color/black</item>
<item name="android:textSelectHandleLeft">@android:color/black</item>
<item name="android:textSelectHandleRight">@android:color/black</item>
</style>
The issue is gone after commenting on the code above, but how to change the selection color?
来源:https://stackoverflow.com/questions/52794950/unresponsive-soft-keyboard-for-a-couple-of-seconds-in-edittext-when-i-move-the-c