Android技术知识Android开发Android开发

Android关于软键盘与输入框的全面使用场景总结

2021-03-15  本文已影响0人  奔跑吧李博

Edittext与软键盘的使用在平时开发中很是常见,因为只要有输入框,就可能会对Edittext进行特殊的操作,比如自动弹出软键盘,禁止自动弹出,监听输入等。

各个场景演示视频:

代码直通车

在进入有Edittext页面的时候,有些机型会默认显示第一个 EditText 的光标,同时弹出键盘,我们默认是不想看到这个光标的,那么可以给这个editText 的公共父布局设置两个属性,就可以解决这个问题。

android:focusable="true/false" 
android:focusableInTouchMode="true"

让edittext自动获取焦点,弹出系统的软键盘。大家在实际使用中很可能会遇到不生效的问题,这里需要加上短时间的延时,不然不会生效。

    /**
     * 自动打开键盘
     */
    private fun showSoftInput(context: Context, et: EditText) {
        Timer().schedule(object : TimerTask() {
            override fun run() {
                (context as Activity).runOnUiThread {
                    et.isFocusable = true
                    et.isFocusableInTouchMode = true
                    //请求获得焦点
                    et.requestFocus()
                    //调用系统输入法
                    val inputManager: InputMethodManager = et
                        .context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    inputManager.showSoftInput(et, 0)
                }
            }
        }, 100)
    }

    /**
     * 自动关闭键盘
     */
    private fun closeSoftInput(editText: EditText, context: Context) {
        val imm = context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
        if (imm.isActive) {
            imm.hideSoftInputFromWindow(editText.applicationWindowToken, 0)
        }
    }

EditText的imeOptions属性有8种,分别是:

actionDone 对应 EditorInfo.IME_ACTION_DONE类型
Enter键显示 完成
actionGo 对应 EditorInfo.IME_ACTION_GO 类型
Enter键显示 前进
actionNext 对应 EditorInfo.IME_ACTION_NEXT 类型
Enter键显示 下一项
actionNone 对应 EditorInfo.IME_ACTION_NONE 类型
Enter键显示 无动作
actionPrevious 对应 EditorInfo.IME_ACTION_PREVIOUS 类型
Enter键显示 上一项
actionSearch 对应 EditorInfo.IME_ACTION_SEARCH 类型
Enter键显示 搜索
actionUnspecified 对应 EditorInfo.IME_ACTION_UNSPECIFIED 类型
Enter键显示 未指定
actionSend 对应 EditorInfo.IME_ACTION_SEND类型
Enter键显示 发送

首先,对edittext添加搜索事件的属性:

android:imeOptions="actionSearch"

代码中设置事件监听:

        etSearch.setOnEditorActionListener(object: TextView.OnEditorActionListener {
            override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
                if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                    var content = etSearch.text.toString().trim()
                    Toast.makeText(applicationContext, "搜索$content", Toast.LENGTH_SHORT).show()
                    return true
                }
                return false
            }
        })
    }

弹出软键盘时,将底部布局弹起在键盘之上,比如底下有提交按钮,就在这个button外嵌套一个scrollview来解决。

 <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Button
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:text="提交"
                android:layout_margin="20dp"
                app:layout_constraintTop_toTopOf="parent"/>
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>

键盘打开关闭监听类,通过屏幕上可见内容高度的改变来判断是否有键盘弹出。此类功能用于对输入框输入完成进行布局状态改变的需求。

public class SoftKeyBoardListener {

    private View rootView;//activity的根视图
    int rootViewVisibleHeight;//纪录根视图的显示高度
    private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;

    public SoftKeyBoardListener(Activity activity) {
        //获取activity的根视图
        rootView = activity.getWindow().getDecorView();

        //监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            //获取当前根视图在屏幕上显示的大小
            Rect r = new Rect();
            rootView.getWindowVisibleDisplayFrame(r);

            int visibleHeight = r.height();
            System.out.println(""+visibleHeight);
            if (rootViewVisibleHeight == 0) {
                rootViewVisibleHeight = visibleHeight;
                return;
            }

            //根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变
            if (rootViewVisibleHeight == visibleHeight) {
                return;
            }

            //根视图显示高度变小超过200,可以看作软键盘显示了
            if (rootViewVisibleHeight - visibleHeight > 200) {
                if (onSoftKeyBoardChangeListener != null) {
                    onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
                }
                rootViewVisibleHeight = visibleHeight;
                return;
            }

            //根视图显示高度变大超过200,可以看作软键盘隐藏了
            if (visibleHeight - rootViewVisibleHeight > 200) {
                if (onSoftKeyBoardChangeListener != null) {
                    onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight);
                }
                rootViewVisibleHeight = visibleHeight;
                return;
            }

        });
    }

    private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
        this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener;
    }

    public interface OnSoftKeyBoardChangeListener {
        void keyBoardShow(int height);

        void keyBoardHide(int height);
    }

    public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
        SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity);
        softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener);
    }
}

使用进行监听代码:

SoftKeyBoardListener.setListener(this, object: SoftKeyBoardListener.OnSoftKeyBoardChangeListener {
            override fun keyBoardShow(height: Int) {
                Toast.makeText(applicationContext, "键盘打开", Toast.LENGTH_SHORT).show()
            }

            override fun keyBoardHide(height: Int) {
                Toast.makeText(applicationContext, "键盘关闭", Toast.LENGTH_SHORT).show()
            }

        })
上一篇 下一篇

猜你喜欢

热点阅读