Android App 一种多输入框切换需求的实现

在汽车车载娱乐系统应用开发中,有相当一部分车机采用宽矮屏幕,即:屏幕的宽度大但高度小。针对这种情况,难免遇到输入法弹出后覆盖内容过多的情况,特别是页面存在多个输入框时,几个输入框既要满足在输入法未弹出时的全屏布局,又要满足输入法弹出时合理适时地出现在用户视野范围内,否则非常影响用户体验。

参考如下需求:

1. 输入法未弹出时,页面中存在多个输入框,并纵向排布,铺满整个屏幕

2. 点击某个输入框时,输入法键盘弹出,键盘会占据大半屏幕,此时需要将点击的输入框聚焦到可见范围

3. 输入法弹出时,拖动非键盘范围可以自由将其他输入框拖至可见范围

4. 当输入框失去焦点时,需要检测当前输入框内容是否符合要求,若不符合,则重新抢回焦点并高亮提示

综上,整个页面涉及到的技术点有:输入法键盘弹出收起的监听,页面焦点切换的监听,字符输入的监听等,废话不多说,看代码:

首先是常规的输入框控件绑定和监听:

    @BindView(R.id.pvPassword)
    Edittext mPasswordView;

    TextListener textListener = new TextListener();
    mPasswordView.addTextChangedListener(textListener);

    FocusListener focusListener = new FocusListener();
    mPasswordView.setOnFocusChangeListener(focusListener);

    KeyboardListener hideListener = new KeyboardListener();
    getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(() -> {
        //此处代码为判断键盘弹出
        InputMethodManager inputManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        int inputWindowVisibleHeight = inputManager.getInputMethodWindowVisibleHeight();
        //监听键盘变化的回调
        if (inputWindowVisibleHeight == 0) {
            hideListener .onHideStatusChanged(true);
        } else {
            hideListener .onHideStatusChanged(false);
        }
    });

 之后是各个Listener的定义:

    public class FocusListener implements View.OnFocusChangeListener {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                updateErrorView(v);    // 更新当前报错显示
            } else {
                // requireCurrentErrorView()为获取当前报错输入框View
                if (requireCurrentErrorView() != null && requireCurrentErrorView() != v) {
                    requireCurrentErrorView().requestFocus();
                } else if (requireCurrentErrorView() == null || requireCurrentErrorView() == v) {
                    getWindow().getDecorView()
                        .postDelayed(SignUpFullScreenDialog.this::resizeEdittext, 300);
                }
            }
        }
    }

    public class TextListener implements TextWatcher {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            // 重置所有edittext View
            updateButtonStatus();
        }
    }


    public class KeyboardListener implements KeyboardStatusChangedListener {
        @Override
        public void onKeyboardStatusChanged(boolean isHide) {
            transformWhileKeyboardHide(isHide);
            if (isHide) {
                if (mLayout != null) {
                    mLayout .smoothScrollTo(0, 0);
                }
            } else {
                getWindow().getDecorView()
                    .postDelayed(SignUpFullScreenDialog.this::resizeEdittext, 300);
            }
        }
    }

最后是关键方法:

    private void resizeEdittext() {
        if (mLayout != null && mET1 != null && mET1.hasFocus()) {
            mLayout.smoothScrollTo(0, 0);
        } else if (mLayout != null && mET2 != null && mET2.hasFocus()) {
            mLayout.smoothScrollTo(0, 136);
        } else if (mLayout != null && mET3 != null && mET3.hasFocus()) {
            mLayout.smoothScrollTo(0, 300);
        } else if (mLayout != null && mET4 != null && mET4.hasFocus()) {
            mLayout.smoothScrollTo(0, 438);
        }
    }

    private void transformWhileKeyboardHide(boolean isHide) {
        if (mLayout != null) {
            ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) mSignUpLayout.getLayoutParams();
            params.height = isHide ? ViewGroup.LayoutParams.WRAP_CONTENT : 248;
            mLayout.setLayoutParams(params);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值