千家信息网

如何使用Android实现一个悬浮在软键盘上的输入栏

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要介绍"如何使用Android实现一个悬浮在软键盘上的输入栏",在日常操作中,相信很多人在如何使用Android实现一个悬浮在软键盘上的输入栏问题上存在疑惑,小编查阅了各式资料,整理出简单好
千家信息网最后更新 2026年11月03日如何使用Android实现一个悬浮在软键盘上的输入栏

这篇文章主要介绍"如何使用Android实现一个悬浮在软键盘上的输入栏",在日常操作中,相信很多人在如何使用Android实现一个悬浮在软键盘上的输入栏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何使用Android实现一个悬浮在软键盘上的输入栏"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    悬浮栏

    实现悬浮栏很简单

    chatInputPanel.setVisibility(View.VISIBLE);chatInputEt.setFocusable(true);chatInputEt.setFocusableInTouchMode(true);chatInputEt.requestFocus();InputMethodManager inputManager = (InputMethodManager)chatInputEt.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);inputManager.showSoftInput(chatInputEt, 0);

    chatInputPanel就是悬浮栏整个layout,mChatPanelContent才是悬浮栏实际部分,chatInputEt是其中的EditText,对它做一些设置就可以实现将chatInputPanel悬浮在软件盘上。

    这里chatInputPanel是全屏的(点击mChatPanelContent以外部分隐藏键盘),mChatPanelContent是在它的bottom底部,默认隐藏(INVISIBLE)。

    横屏时软键盘全屏

    横屏时,安卓默认会将软键盘全屏显示,这样无法实现悬浮栏。所以需要取消全屏显示

    在EditText中使用android:imeOptinos可对Android自带的软键盘进行一些界面上的设置

    • android:imeOptions="flagNoExtractUi" //使软键盘不全屏显示,只占用一部分屏幕

    • android:imeOptions="actionNone" //输入框右侧不带任何提示

    • android:imeOptions="actionGo" //右下角按键内容为'开始'

    • android:imeOptions="actionSearch" //右下角按键为放大镜图片,搜索

    • android:imeOptions="actionSend" //右下角按键内容为'发送'

    • android:imeOptions="actionNext" //右下角按键内容为'下一步'

    • android:imeOptions="actionDone" //右下角按键内容为'完成'

    所以我们为EditText设置android:imeOptions="flagNoExtractUi"即可实现在横屏时不全屏显示。同时,可能EditText添加相应的监听器,捕捉用户点击了软键盘右下角按钮的监听事件,以便进行处理。

    editText.setOnEditorActionListener(new OnEditorActionListener() {           @Override          public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {               Toast.makeText(MainActivity.this, "text2", Toast.LENGTH_SHORT).show();               return false;           }       });

    监听软键盘(该方法不可靠,废弃,下面有靠谱的)

    注意:这是网上的一个错误方法,所以特意拿出来说一下,不感兴趣直接去看(3)即可。

    显示没问题了,但是软键盘隐藏的时候要求悬浮栏同步隐藏起来。

    系统并没有提供监听软键盘收起的api,所以我们只能自己实现。

    chatInputPanel.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {    @Override    public void onGlobalLayout() {        if(chatInputPanel.getBottom() > container.getRootView().getHeight() / 2){            chatInputPanel.setVisibility(View.INVISIBLE);        }        else{            chatInputPanel.setVisibility(View.VISIBLE);        }    }});

    监听chatInputPanel(悬浮栏整体布局)的布局变化,当底部大于rootview高度一半的时候隐藏,否则显示。

    因为我们的功能是横屏的,所以键盘弹起时,chatInputPanel因为悬浮在键盘上,所以底部一定小于rootview高度(屏幕宽度)一半。

    当收起键盘,chatInputPanel会回到最底部(设置是在父布局底部),所以底部一定大于一半。

    这个方法不靠谱,而且重绘会导致onGlobalLayout频繁的执行,虽然可以加上一个时间来控制,但是不推荐使用这个方式来监听软键盘,下面看看另外一种方式。

    靠谱的监听软键盘的方法

    上面的方法为什么不考虑,是因为全屏显示FLAG_FULLSCREEN(隐藏通知栏)导致问题

    当我们需要全屏显示隐藏通知栏时,会使用FLAG_FULLSCREEN属性

    getActivity().getWindow().setFlags(        WindowManager.LayoutParams.FLAG_FULLSCREEN,        WindowManager.LayoutParams.FLAG_FULLSCREEN);

    但是会影响上面的悬浮栏,因为发现chatInputPanel.getBottom()始终没变化,但是我们判断显示隐藏就靠这个变化。

    没变化是因为android在全屏FLAG_FULLSCREEN的处理方式导致的,全屏时软键盘会出现很多问题,这个网上有很多。

    如何解决?

    我们换一种方式监听软键盘即可

    getActivity().getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {    @Override    public void onGlobalLayout() {        Rect rect = new Rect();        rootView.getWindowVisibleDisplayFrame(rect);        int rootHeight=rootView.getRootView().getHeight();        int displayHeight=rect.height();        int diffHeight=rootHeight-displayHeight;        if(diffHeight==0){            //键盘收起            chatInputPanel.setVisibility(View.INVISIBLE);        }else{            //键盘弹出            chatInputPanel.setVisibility(View.VISIBLE);        }    }});

    通过监听根布局种的content布局的变化来判断,目前这个方法是最靠谱的。

    但是还存在一个小问题,就是全屏状态下键盘会覆盖悬浮栏底部的一小部分,这个怎么办?

    终极悬浮方式

    上面解决了软键盘的监听问题,但是全屏状态下悬浮栏总会被遮住一部分,那怎么办?

    其实这里还有一个问题,当显示键盘后,app中的布局整体被向上推起,这样导致部分组件缩小等情况。

    我们要首先解决这个问题,让app的布局整体保持不动,键盘覆盖在其上面,这需要在弹起键盘前手动设置一下,如下:

    mChatInput.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        DisplayMetrics metric = new DisplayMetrics();        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metric);        chatInputPanel.setY(-metric.heightPixels);//解决首次可能向上推的问题                chatInputEt.setFocusable(true);        chatInputEt.setFocusableInTouchMode(true);        chatInputEt.requestFocus();        InputMethodManager inputManager = (InputMethodManager)chatInputEt.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);        inputManager.showSoftInput(chatInputEt, 0);    }});

    这样将悬浮栏移到了最顶部以上,就不会出现上推的情况了(猜测与键盘的机制有关,因为键盘弹出如果遮挡了有焦点的输入组件就好重新调整窗口,我们将悬浮窗放在最上面,键盘怎么也不会遮挡到焦点的EditText,所以不会重新调整窗口)。

    但是这样悬浮栏就一直看不见了,而且我们可以看到在这里去掉了chatInputPanel.setVisibility(View.VISIBLE);代码,那么如何显示?

    上面我们提到使用OnGlobalLayoutListener方式监听键盘,我们就在这里显示即可,同时优化一下显示的位置,在这里计算窗口显示区域上移多少,让chatInputPanel也上移相应位置即可,如:

    private int mLastHeight = 0;getActivity().getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {    @Override    public void onGlobalLayout() {        Rect rect = new Rect();        getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);        int height = rect.height();        int rawHeight = getResources().getDisplayMetrics().heightPixels - rect.top;        if (height == mLastHeight)            return;                    if (height < rawHeight) {            UiThreadHandler.postDelayed(new Runnable() {                @Override                public void run() {                    chatInputPanel.setVisibility(View.VISIBLE);                    chatInputPanel.setTranslationY(-(rawHeight - height));                }            }, 200);        } else {            UiThreadHandler.postDelayed(new Runnable() {                @Override                public void run() {                    chatInputPanel.setVisibility(View.GONE);                }            }, 100);        }                        mLastHeight = height;        }});

    可以看到先得到当前窗口的显示高度和屏幕的实际高度(窗口部分)

    然后先判断窗口显示区域是否变化了,如果没变化则不处理。

    如果有变化,则判断变大还是变小了。

    如果变小了

    说明键盘弹起,这时候显示chatInputPanel,同时设置translationY为-(rawHeight - height)

    首先chatInputPanel初始位置底部是与屏幕底部对齐的,虽然设置了setY,但是setY实际上就是setTranslationY,初始位置没变,源码:

    public void setY(float y) {    setTranslationY(y - mTop);}

    而弹起键盘后想要显示在键盘以上,那么就需要从最底部向上移动一个键盘的高度,键盘高度就是rawHeight - height,所以向上移动是将translationY设置为-(rawHeight - height)。

    如果变大了

    说明键盘收起,隐藏chatInputPanel即可。

    这样不仅解决了窗口推起的问题,也同时解决了软键盘遮挡部分悬浮栏的问题,因为悬浮栏的位置是通过计算得到的,不是通过软键盘上推导致布局调整而改变位置的。

    到此,关于"如何使用Android实现一个悬浮在软键盘上的输入栏"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

    键盘 问题 监听 底部 布局 变化 方法 输入 位置 方式 部分 高度 按键 内容 同时 就是 屏幕 学习 实际 整体 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州淘业互联网络科技 科技互联网项目 疫情对互联网科技公司影响 互联网公司 科技公司 西安互联网科技 南京欣网互联网科技 互联网金融科技平台 互联网科技博客 盛创互联网科技有限公司 互联网巨头投资的硬核科技 济南和联互联网科技有限公司 团飞科技与伯堂互联网服务平台 宜昌元轩互联网科技有限公司 深圳市优智互联网科技有限公司 内蒙古九一互联网科技 黑科技 体验场景 互联网大会 中天科技中国工业互联网 宇信科技在杭州互联网排第几 上海万顺科技互联网有限公司招聘 互联网科技品牌 亿人帮互联网科技有限公司 互联网为科技 互联网与未来科技 云电互联网科技 温州喔噻互联网科技有限公司 未来五年的互联网科技 江苏苏星互联网科技有限公司 江苏互联网智能科技产品出厂价 中国互联网公司的科技投入 瑞安市蟠桃会互联网科技有限公司
    0