关于android 软件盘,收起,光标等

此文章可解决点击除输入框外的其他地方使得输入法的软件盘消失(收起)
监听输入法软件盘的打开收起状态
解决输入法收起后输入框光标问题

KeyboardStateObserver:这个类可以监听软件盘收起和放开的状态
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

import com.maxus.logger.Logger;

public class KeyboardStateObserver {
    private static final String TAG = KeyboardStateObserver.class.getSimpleName();
    public static KeyboardStateObserver getKeyboardStateObserver(Activity activity) {
        return new KeyboardStateObserver(activity);
    }
    private View mChildOfContent;
    private int usableHeightPrevious;
    private OnKeyboardVisibilityListener listener;
    public void setKeyboardVisibilityListener(OnKeyboardVisibilityListener listener) {
        this.listener = listener;
    }
    private KeyboardStateObserver(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
    }
    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard / 4)) {
                if (listener != null) {
                    listener.onKeyboardShow();
                }
            } else {
                if (listener != null) {
                    listener.onKeyboardHide();
                }
            }
            usableHeightPrevious = usableHeightNow;
            Logger.d(TAG,"usableHeightNow: " + usableHeightNow + " | usableHeightSansKeyboard:" + usableHeightSansKeyboard + " | heightDifference:" + heightDifference);
        }
    }
    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        Logger.d(TAG,"rec bottom>" + r.bottom + " | rec top>" + r.top);
        return (r.bottom - r.top);// 全屏模式下: return r.bottom
    }
    public interface OnKeyboardVisibilityListener {
        void onKeyboardShow();
        void onKeyboardHide();
    }
}
在activity 的onCreate 中使用
KeyboardStateObserver.getKeyboardStateObserver(this)
    .setKeyboardVisibilityListener(object : OnKeyboardVisibilityListener {
        override fun onKeyboardShow() {
            Logger.d(TAG, "wgx onKeyboardShow")
        }

        override fun onKeyboardHide() {
            Logger.d(TAG, "wgx onKeyboardHide")

           //键盘收起时使输入框的光标消失
            et.setFocusable(false)
            et.setFocusableInTouchMode(true)
        }
    })

点击空白处 ,收起软件盘

override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
    if (ev.action === MotionEvent.ACTION_DOWN) {
        // 获得当前得到焦点的View,一般情况下就是EditText(特殊情况就是轨迹求或者实体案件会移动焦点)
        val v = currentFocus
        //   mBinding.blessTypeEdit.blessMessage.isCursorVisible = v== mBinding.blessTypeEdit.blessMessage
        if (isShouldHideInput(v, ev)) {
            hideSoftInput(v!!.windowToken)
        }
    }
    return super.dispatchTouchEvent(ev)
}

 private fun isShouldHideInput(v: View?, event: MotionEvent): Boolean {
        if (v != null && v is EditText) {
            val leftTop = intArrayOf(0, 0)
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop)
            val left = leftTop[0]
            val top = leftTop[1]
            val bottom = top + v.getHeight()
            val right = left + v.getWidth()
            return if (event.x > left && event.x < right && event.y > top && event.y < bottom) {
                // 点击的是输入框区域,保留点击EditText的事件
                false
            } else {
                //使EditText触发一次失去焦点事件
                v.setFocusable(false)
                //                v.setFocusable(true); //这里不需要是因为下面一句代码会同时实现这个功能
                v.setFocusableInTouchMode(true)
                true
            }
        }
        return false
    }


    /**
     * 多种隐藏软件盘方法的其中一种
     *
     * @param token
     */
    private fun hideSoftInput(token: IBinder?) {
        if (token != null) {
            var im: InputMethodManager? = null
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
                im = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
                im!!.hideSoftInputFromWindow(
                    token,
                    InputMethodManager.HIDE_NOT_ALWAYS
                )
            }
        }
    }
}

你可能感兴趣的:(android,java,开发语言)