Android优雅地判断软键盘弹出状态

  • 一、为什么要判断软键盘弹出状态
  • 二、已有的判断方案
  • 三、设计新的方案
  • 四、实现效果
  • 五、完整代码
  • 六、核心代码
  • 七、下载地址

一、为什么要判断软键盘弹出状态

神马笔记在完成笔记编辑时,会对编辑界面进行截图以作为笔记的图标。为了保证图标的一致性,需要在关闭软键盘后进行截图,否则会产生2种尺寸的截图大小。

因此,需要判断软键盘是否弹出。如果软键盘弹出,则先关闭软键盘,用户才能退出编辑。

二、已有的判断方案

http://www.cnblogs.com/shelly-li/p/5639833.html

https://blog.csdn.net/yijiaodingqiankun/article/details/81085167?utm_source=blogxgwz5

https://blog.csdn.net/sinat_31311947/article/details/53899166

https://blog.csdn.net/javazejian/article/details/52126391

所有方案一致指向,根据布局变化来判断软键盘是否弹出是最稳妥的实现方案。

三、设计新的方案

首先,需要设置Activity的windowSoftInputMode属性为adjustResize

当软键盘状态发生变化时,布局会相应地发生变化。再根据布局变化来判断软键盘状态。

其次,监听Activity的android.R.id.content控件的布局变化。

android.R.id.content是每个Activity的用户控件的容器,存在于每一个Activity中,所以我们监听android.R.id.content的变化可以适应所有的Activity。

再来,使用LifecycleObserver来感知Activity的状态变化,从而决定何时启动布局变化监听。

最后,使用ActivityLifecycleCallbacks关心其他Activity的变化,获取Bottom的最大值,比较当前Bottom值以及最大Bottom值,从而判断软键盘的状态。

四、实现效果

注意左上角的变化。

软键盘弹出时,显示为“完成”按钮。

软键盘关闭时,显示为“返回”图标。

五、完整代码

package club.andnext.helper;import android.app.Activity;
import android.app.Application;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;/****/
public class SoftInputHelper implements LifecycleObserver,Application.ActivityLifecycleCallbacks,ViewTreeObserver.OnGlobalLayoutListener {private static final String TAG = SoftInputHelper.class.getSimpleName();int bottom;boolean visible;Rect rect;OnSoftInputListener onSoftInputListener;FragmentActivity context;public SoftInputHelper(FragmentActivity context) {this.context = context;this.bottom = 0;this.visible = false;this.rect = new Rect();context.getLifecycle().addObserver(this);}@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)public void onCreate() {context.getApplication().registerActivityLifecycleCallbacks(this);}@OnLifecycleEvent(Lifecycle.Event.ON_START)public void onStart() {ViewTreeObserver observer = getViewTreeObserver(context);if (observer != null && observer.isAlive()) {observer.addOnGlobalLayoutListener(this);}}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)public void onStop() {ViewTreeObserver observer = getViewTreeObserver(context);if (observer != null && observer.isAlive()) {observer.removeOnGlobalLayoutListener(this);}}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)public void onDestroy() {context.getApplication().unregisterActivityLifecycleCallbacks(this);context.getLifecycle().removeObserver(this);}@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {}@Overridepublic void onActivityStarted(Activity activity) {}@Overridepublic void onActivityResumed(Activity activity) {}@Overridepublic void onActivityPaused(Activity activity) {}@Overridepublic void onActivityStopped(Activity activity) {this.updateBottom(activity);}@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) {}@Overridepublic void onActivityDestroyed(Activity activity) {}@Overridepublic void onGlobalLayout() {{this.updateBottom(context);}View target = getView(context);if (target != null) {target.getGlobalVisibleRect(rect);boolean result = rect.bottom < bottom;if (this.visible ^ result) {this.visible = result;if (onSoftInputListener != null) {onSoftInputListener.onSoftInputChanged(this, visible);}}}}public int getBottom() {return bottom;}public void setOnSoftInputListener(OnSoftInputListener listener) {this.onSoftInputListener = listener;}void updateBottom(Activity activity) {View view = getView(activity);if (view != null) {view.getGlobalVisibleRect(rect);bottom = (bottom < view.getBottom())? view.getBottom(): bottom;bottom = (bottom < rect.bottom)? rect.bottom: bottom;}Log.v(TAG, "bottom = " + bottom);}View getView(Activity activity) {View view = activity.getWindow().getDecorView().findViewById(android.R.id.content);return view;}ViewTreeObserver getViewTreeObserver(Activity activity) {View view = getView(activity);if (view == null) {return null;}return view.getViewTreeObserver();}/****/public interface OnSoftInputListener {void onSoftInputChanged(SoftInputHelper helper, boolean visible);}
}

六、核心代码

  1. 计算最大Bottom值

需要最大Bottom值作为参考值,比较当前bottom及最大bottom,从而判断软键盘状态。

    void updateBottom(Activity activity) {View view = getView(activity);if (view != null) {view.getGlobalVisibleRect(rect);bottom = (bottom < view.getBottom())? view.getBottom(): bottom;bottom = (bottom < rect.bottom)? rect.bottom: bottom;}Log.v(TAG, "bottom = " + bottom);}
  1. 判断软键盘是否弹出

将当前bottom与最大bottom比较,从而得出结论。

    @Overridepublic void onGlobalLayout() {{this.updateBottom(context);}View target = getView(context);if (target != null) {target.getGlobalVisibleRect(rect);boolean result = rect.bottom < bottom;if (this.visible ^ result) {this.visible = result;if (onSoftInputListener != null) {onSoftInputListener.onSoftInputChanged(this, visible);}}}}

七、下载地址

神马笔记最新版本:【whatsnote_lastest.apk】

Android优雅地判断软键盘弹出状态相关推荐

  1. Android判断软键盘弹出并隐藏的简单完美解决方案

    Android判断软键盘弹出并隐藏的简单完美解决方案 参考文章: (1)Android判断软键盘弹出并隐藏的简单完美解决方案 (2)https://www.cnblogs.com/thare1307/ ...

  2. android webview监听软键盘弹出和隐藏来修改虚拟导航栏颜色

    最近项目中用到了webview,然后里面有输入框,当我们点击输入框的时候,软键盘挡住了布局,这就尴尬了,并且产品说,只有在软键盘弹出的时候底部的虚拟导航栏为黑色,软键盘隐藏的时候虚拟导航栏应该也隐藏. ...

  3. android判断键盘是否弹出窗口,Android判断软键盘弹出并隐藏的简单完美解决方法(推荐)...

    最近项目中有一个编辑框,下面是个ListView.在触发编辑框弹出软键盘后,ListView还能滑动,并且ListView的item还能响应单击.这样的体验效果很不好.于是便想在滑动或单击item时判 ...

  4. android弹出键盘高度,Android 解决全面屏 软键盘弹出会有高度约50dp的白条。

    效果对比图片先走 解决前效果图 T_X0~JU{WQ2FC1W$M})J%1S.jpg 解决完成后效果图 0EBFD68FC050B16866B81321E0FD9C62.jpg /** * @aut ...

  5. android 软件盘弹回去的最好体验,Android 软键盘弹出 日常填坑

    开发输入框的开发者都会遇到一个问题,那就是在登录界面时,当你点击输入框时,下边的按钮有时会被输入框挡住,这个不利于用户的体验,所以很多人希望软键盘弹出时,也能把按钮挤上去.这样的交互更人性化,做得合理 ...

  6. android软键盘弹出底部有黑色闪出,vue移动端安卓软键盘弹出底部按钮顶起

    在做一个基于企业微信的h5移动页面时,当软键盘弹出时,底部fixed定位在ios上没事,安卓手机上,底部按钮会被顶起到软键盘,查看原应时由于软键盘顶起时,安卓设备的视图会变小.造成固定定位按钮呗顶起. ...

  7. (转)Android软键盘弹出,界面整体上移

    原地址:http://blog.csdn.net/u011622479/article/details/51161717 在做搜索功能的时候,点击搜索框,搜索框获取焦点,键盘弹出:现在问题出来了,an ...

  8. 解决Android软键盘弹出覆盖h5页面输入框问题 // 在ios系统中输入框软键盘消失后,页面不回弹的问题 // 解决苹果不回弹页面 // 微信环境打开

    //解决Android软键盘弹出覆盖h5页面输入框问题 window.addEventListener('resize', () => {if (document.activeElement.t ...

  9. Android 软键盘弹出时布局内指定内容上移实现及问题解决

    Android 软键盘弹出时布局内指定内容上移实现及问题解决 参考文章: (1)Android 软键盘弹出时布局内指定内容上移实现及问题解决 (2)https://www.cnblogs.com/as ...

  10. Android 软键盘弹出时把布局顶上去,控件乱套解决方法

    Android 软键盘弹出时把布局顶上去,控件乱套解决方法 参考文章: (1)Android 软键盘弹出时把布局顶上去,控件乱套解决方法 (2)https://www.cnblogs.com/zhuj ...

最新文章

  1. 简单介绍python连接telnet和ssh的两种方式
  2. 【NodeJS】运行在服务端的JavaScript
  3. SAP 电商云 Spartacus UI 的自定义 hamburger 菜单
  4. Oracle .事物,提交,回滚
  5. Python int与string 的转换
  6. 蓝桥杯 ALGO-27 算法训练 FBI树 Java版
  7. php选择版本,怎样选择PHP的版本
  8. 2021WordPress转z-blog搬家教程_WordPress搬家zblog博客程序工具
  9. NSGA-Ⅱ算法原理
  10. 常用CSS的命名规范:
  11. 计算机文件自定义排序6,文件夹如何自定义排序
  12. 智能安防视频监控平台页面无法访问该如何排查?
  13. hdu5454 Excited Database (线段树)
  14. 安卓Android基于百度云平台人脸识别学生考勤签到系统设计
  15. 扫黑除恶进行中,公众号文章不知道怎样排版?看这里。
  16. 我最喜爱的九位历史人物 - 曾国藩(Space搬家)
  17. 利用机器学习方法对猪肉价格预测
  18. 蓝牙规范-Vol 6:低功耗控制器 Part A 物理层规范
  19. [创新工具和方法论]-01- DOE课程基础知识
  20. (转)Ubuntu 17.04_64上搭建巡风扫描系统(资产信息漏洞扫描内网神器)

热门文章

  1. 浅谈工业4.0时代,深信服adesk桌面云如何助力智能工厂.
  2. python-微信自动发送信息
  3. 微型计算机原理与应用简称为啥,微型计算机原理与应用知识点总结.pdf
  4. pc连接用hybrid,并untagged,交换机用trunk
  5. cad刷新快捷键_CAD快捷键命令
  6. 学习记录:xmind2testcase测试用例模板
  7. 麻省理工18年春软件构造课程阅读10“抽象数据类型”
  8. 毕业2年鏖战美团、京东、阿里3个大厂,成功拿到2个offer,我的社招Java岗面试经历分享
  9. Linux 内核读写文件
  10. WPF框架下,窗体的嵌套显示