Android N(7.0) 在ListView里显示EditText时软键盘弹出时会自动切换到全键盘的问题?
问题症状描述
- Activity 在AndroidManifest.xml里设置
android:windowSoftInputMode="adjustPan"
- 在ListView里绘制Item
- Item控件为EditText
- EditText设置InputType为Number
- 当在Android 7.0系统上,点击EditText时,弹出的软键盘为“数字”输入模式,但是瞬间就会切换到“全键盘”模式。
在7.0之前的系统,都没有出现这种问题。
尝试性解决方案(风险未评估)
/** * 尝试性修复了在ListView里显示EditText InputType为 其它非text 类型时,弹出的软键盘会从数字键盘自动切换为 英文全键盘 的问题。 */class ListViewEx2 extends ListView{public ListViewEx2(final Context context){ super(context);}public ListViewEx2(final Context context, final AttributeSet attrs){ super(context, attrs);}public ListViewEx2(final Context context, final AttributeSet attrs, final int defStyleAttr){ super(context, attrs, defStyleAttr);}@TargetApi(Build.VERSION_CODES.LOLLIPOP)public ListViewEx2(final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes){ super(context, attrs, defStyleAttr, defStyleRes);}@Overrideprotected void onLayout(final boolean changed, final int l, final int t, final int r, final int b){ //XXX:经过初步测试,只有在Android 7.0平台以上的系统才会出现软键盘自动切换的问题。 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && changed) super.onLayout(changed, l, t, r, b); else super.onLayout(changed, l, t, r, b);}}
ListView.java 源码对比
Android 7.0 部分可疑的改动过的源码
private class FocusSelector implements Runnable { // the selector is waiting to set selection on the list view private static final int STATE_SET_SELECTION = 1; // the selector set the selection on the list view, waiting for a layoutChildren pass private static final int STATE_WAIT_FOR_LAYOUT = 2; // the selector's selection has been honored and it is waiting to request focus on the // target child. private static final int STATE_REQUEST_FOCUS = 3; public void run() { if (mAction == STATE_SET_SELECTION) { setSelectionFromTop(mPosition, mPositionTop); mAction = STATE_WAIT_FOR_LAYOUT; } else if (mAction == STATE_REQUEST_FOCUS) { final int childIndex = mPosition - mFirstPosition; final View child = getChildAt(childIndex); if (child != null) { child.requestFocus(); } mAction = -1; } } }}
Android 6.0 部分可疑的改动过的对应旧版本源码
private class FocusSelector implements Runnable { public void run() { setSelectionFromTop(mPosition, mPositionTop); } }