项目中用到软键盘的管理总结如下:
在开始进入页面时不弹出键盘
方法一:在包含EditText外层布局上添加
android:focusable="true" android:focusableInTouchMode="true"
抢在EditText获取焦点,即可
原理 view touch source:
public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... }
即一个子view想要获取焦点必须满足clickable, focusable, focusableInTouchMode 属性为true,缺一不可.
方法二:在onResume中加入这行代码
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
软键盘出现把原来的布局底部拦布局给顶上去的方法解决办法:
android:windowSoftInputMode="adjustPan|stateHidden"
将按钮恰好显示在键盘之上?
<activity
android:windowSoftInputMode="adjustResize"
当键盘弹起时,Activity就会重新布局,以键盘的上方作为整个页面布局的底部。我们只需要将“NEXT”按钮的属性设置为:
android:layout_alignParentBottom="true"
不是一个页面的,一个activity,多个页面的,每个页面只是一个Fragment
在按钮的布局之上,添加了一个高度为0dp的ScrollView才解决
<ScrollView android:layout_width="match_parent" android:layout_height="0dp" /> <Button android:id="@+id/entry_btn" android:layout_width="match_parent" android:layout_height="45dp" android:layout_alignParentBottom="true"
1,绑定软键盘到EditText:
edit.setFocusable(true); edit.setFocusableInTouchMode(true); edit.requestFocus(); InputMethodManager inputManager = (InputMethodManager)edit.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.showSoftInput(edit, 0);
2,点击空白区域去除EditText软键盘显示:
重写Activity dispatchTouch
@Override public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if ( v instanceof EditText) { Rect outRect = new Rect(); v.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { v.clearFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); }
EditText始终不弹出软件键盘
EditText edit=(EditText)findViewById(R.id.edit); edit.setInputType(InputType.TYPE_NULL);
还可以
InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if(imm.isActive()){ //这里可以判断也可以不判断 imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0 ); }
1,在设置软键盘弹出属性界面加载后,软键盘不能弹出,不能弹出软键盘的主要原因是Android程序未将屏幕绘制完成,所以延迟一定时间,弹出软键盘。 方法一: private Handler hander=new Handler(){ public void handleMessage(android.os.Message msg) { edit.setFocusable(true); edit.setFocusableInTouchMode(true); edit.requestFocus(); InputMethodManager inputManager = (InputMethodManager)edit.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.showSoftInput(edit, 0); }; }; @Override public void onWindowFocusChanged(boolean hasWindowFocus) { if(visible){ hander.sendEmptyMessageDelayed(0, 1000); } } 方法二: Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { InputMethodManager m = (InputMethodManager) editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); m.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); } }, 300);
<activity android:windowSoftInputMode="stateVisible|adjustResize" . . . >
该Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间
软键盘打开,关闭监控:来源girhub:
import android.app.Activity; import android.os.Build; import android.view.View; import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowManager; import java.lang.ref.WeakReference; /** * Created by froger_mcs on 21/03/16. */ public class KeyboardWatcher { private WeakReference<Activity> activityRef; private WeakReference<View> rootViewRef; private WeakReference<OnKeyboardToggleListener> onKeyboardToggleListenerRef; private ViewTreeObserver.OnGlobalLayoutListener viewTreeObserverListener; public KeyboardWatcher(Activity activity) { activityRef = new WeakReference<>(activity); initialize(); } public void setListener(OnKeyboardToggleListener onKeyboardToggleListener) { onKeyboardToggleListenerRef = new WeakReference<>(onKeyboardToggleListener); } public void destroy() { if (rootViewRef.get() != null) if (Build.VERSION.SDK_INT >= 16) { rootViewRef.get().getViewTreeObserver().removeOnGlobalLayoutListener(viewTreeObserverListener); } else { rootViewRef.get().getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserverListener); } } private void initialize() { if (hasAdjustResizeInputMode()) { viewTreeObserverListener = new GlobalLayoutListener(); rootViewRef = new WeakReference<>(activityRef.get().findViewById(Window.ID_ANDROID_CONTENT)); rootViewRef.get().getViewTreeObserver().addOnGlobalLayoutListener(viewTreeObserverListener); } else { throw new IllegalArgumentException(String.format("Activity %s should have windowSoftInputMode=\"adjustResize\"" + "to make KeyboardWatcher working. You can set it in AndroidManifest.xml", activityRef.get().getClass().getSimpleName())); } } private boolean hasAdjustResizeInputMode() { return (activityRef.get().getWindow().getAttributes().softInputMode & WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) != 0; } private class GlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener { int initialValue; boolean hasSentInitialAction; boolean isKeyboardShown; @Override public void onGlobalLayout() { if (initialValue == 0) { initialValue = rootViewRef.get().getHeight(); } else { if (initialValue > rootViewRef.get().getHeight()) { if (onKeyboardToggleListenerRef.get() != null) { if (!hasSentInitialAction || !isKeyboardShown) { isKeyboardShown = true; onKeyboardToggleListenerRef.get().onKeyboardShown(initialValue - rootViewRef.get().getHeight()); } } } else { if (!hasSentInitialAction || isKeyboardShown) { isKeyboardShown = false; rootViewRef.get().post(new Runnable() { @Override public void run() { if (onKeyboardToggleListenerRef.get() != null) { onKeyboardToggleListenerRef.get().onKeyboardClosed(); } } }); } } hasSentInitialAction = true; } } } public interface OnKeyboardToggleListener { void onKeyboardShown(int keyboardSize); void onKeyboardClosed(); } }
使用监控:
<activity android:name=".MainActivity" android:windowSoftInputMode="adjustResize" /> keyboardWatcher = new KeyboardWatcher(this); keyboardWatcher.setListener(this);
Kotlin扩展解决View focus弹出键盘时机
fun View.focusAndShowKeyboard() { /** * This is to be called when the window already has focus. */ fun View.showTheKeyboardNow() { if (isFocused) { post { // We still post the call, just in case we are being notified of the windows focus // but InputMethodManager didn't get properly setup yet. val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT) } } } requestFocus() if (hasWindowFocus()) { // No need to wait for the window to get focus. showTheKeyboardNow() } else { // We need to wait until the window gets focus. viewTreeObserver.addOnWindowFocusChangeListener( object : ViewTreeObserver.OnWindowFocusChangeListener { override fun onWindowFocusChanged(hasFocus: Boolean) { // This notification will arrive just before the InputMethodManager gets set up. if (hasFocus) { this@focusAndShowKeyboard.showTheKeyboardNow() // It’s very important to remove this listener once we are done. viewTreeObserver.removeOnWindowFocusChangeListener(this) } } }) } }
自定义EditText
class FixedKeyboardEditText(context: Context, attributeSet: AttributeSet?) : EditText(context, attributeSet) { private var showKeyboardDelayed = false /** * Will request focus and try to show the keyboard. * It has into account if the containing window has focus or not yet. * And delays the call to show keyboard until it's gained. */ fun focusAndShowKeyboard() { requestFocus() showKeyboardDelayed = true maybeShowKeyboard() } @Override override fun onWindowFocusChanged(hasWindowFocus: Boolean) { super.onWindowFocusChanged(hasWindowFocus); maybeShowKeyboard() } private fun maybeShowKeyboard() { if (hasWindowFocus() && showKeyboardDelayed) { if (isFocused) { post { val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.showSoftInput(this@FixedKeyboardEdit, InputMethodManager.SHOW_IMPLICIT) } } showKeyboardDelayed = false } } }
参考:https://developer.squareup.com/blog/showing-the-android-keyboard-reliably