uni app 使用android原生插件页面EditText很不友好,点击EditText会出现键盘遮盖插件页面或者键盘频繁跳动问题。

解决方案:

  • 原理:获取当前页面底层content的高度activity.findViewById(android.R.id.content).getChildAt(0),监听底层content的变化,高度改变后,再触发布局更新
mContentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {public void onGlobalLayout() {//软键盘弹出、系统导航栏隐藏显示均会触发这里// 有变化就 setHeight(Integer);}
});
// 这里再做个防抖
private void setHeight(int height) {if (mFrameLayoutParams.height != height) {// 不必要的更新就不要了mContentView.postDelayed(() -> {// 键盘弹起uni已经更新了,就不用再次更新// uni 没更新,不更新,所以搞个延迟更新布局if (mFrameLayoutParams.height != height) {mFrameLayoutParams.height = height;mContentView.requestLayout();// 触发布局更新}}, 20);}
}

详细代码如下:

  • MyPandoraEntryActivity下延迟初始化单例
SoftKeyboardFixerForFullscreenUtil.assistActivity(this);//建议延迟1秒初始化
  • SoftKeyboardFixerForFullscreenUtil完整代码如下
/*** 解决全屏Activity的键盘档住输入框* 来自:https://blog.csdn.net/passerby_b/article/details/82686662* 注意:* 1.要在setContentView之后调用 assistActivity(activity)!* 2.要是横屏输入法不是满屏的,就需要自己适配了!* 3.自测没有发现问题,但无法100%保证兼容性~* 4.分屏模式下的处理,不知道会不会有其他问题,如果不是刚需,建议还是通过setSoftInputMode尝试调整~~~* <p>* 更新 Cooper 2018-9-13 13:27:59* 1.解决虚拟导航栏隐藏显示布局不自动适配的问题(三星Note8 8.0实测横屏竖屏都没问题,Vivo没有虚拟按键的机器6.0测试没有问题)* 2.解决分屏模式下不适配的问题(三星Note8 8.0实测横屏竖屏都没问题)* 3.优化代码* <p>* 参考:https://blog.csdn.net/smileiam/article/details/69055963* 参考:https://blog.csdn.net/auccy/article/details/80632429* 参考:https://github.com/yy1300326388/AndroidBarUtils/blob/master/app/src/main/java/cn/zsl/androidbarutils/utils/AndroidBarUtils.java* 其实最初的原版就是 AndroidBug5497Workaround ,但是原版考虑的不够全面,尤其是虚拟导航栏的问题,没有考虑进去* 参考:https://www.jianshu.com/p/a95a1b84da11*/public class SoftKeyboardFixerForFullscreenUtil {public static void assistActivity(Activity activity) {new SoftKeyboardFixerForFullscreenUtil(activity);}private final View mContentView;//我们设置的contentViewprivate final FrameLayout.LayoutParams mFrameLayoutParams;//我们设置的contentView的layoutParams//    private boolean isNavigationShowing = false;//没有用到这个
//    private boolean isFullscreenMode = false;//没有用到这个
//    private int barNavigationHeight = 0;//虚拟导航栏高度,没用
//    private int barNavigationWidth = 0;//虚拟导航栏宽度,没用private int barStatusHeight = 0;//状态栏高度private int lastUsableHeight = 0;//上一次的可用高度
//    private int lastUsableWidth = 0;//上一次的可用宽度private SoftKeyboardFixerForFullscreenUtil(final Activity activity) {//region 本来是想通过这个监听虚拟按键,结果发现这个回调比布局回调要晚,所以不用了。放在这里是为了给以后提供一些思路。
//        //1.为DecorView添加系统组件的可见变更事件
//        View decorView = activity.getWindow().getDecorView();
//        isNavigationShowing = ((decorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0);
//        isFullscreenMode = ((decorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0);//api 16以上
//        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {//参考:https://blog.csdn.net/auccy/article/details/80632429
//            @Override
//            public void onSystemUiVisibilityChange(int visibility) {//                if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {//                    isNavigationShowing = true;
//                } else {//                    isNavigationShowing = false;
//                }
//                if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {//                    isFullscreenMode = true;
//                } else {//                    isFullscreenMode = true;
//                }
//            }
//        });//endregion//1.获取 状态栏 高度,获取 导航栏 高度、宽度(横屏用到的,可是横屏在手机上输入法会满屏,不知道不满屏的情况,所以不处理了,要是你遇到了,自行按照横屏的方式解决吧)barStatusHeight = getStatusBarHeight(activity);//barNavigationHeight = getNavigationBarHeight(activity);//barNavigationWidth = getNavigationBarWidth(activity);//2.找到Activity的最外层布局控件,它其实是一个DecorView,它所用的控件就是FrameLayoutfinal FrameLayout content = activity.findViewById(android.R.id.content);//3.获取到setContentView放进去的ViewmContentView = content.getChildAt(0);//4.拿到我们设置的View的布局参数,主要是调整该参数来实现软键盘弹出上移mFrameLayoutParams = (FrameLayout.LayoutParams) mContentView.getLayoutParams();//5.给我们设置的View添加布局变动的监听,来实现布局动作(虚拟导航栏的弹出收起也会触发该监听!)mContentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {public void onGlobalLayout() {//软键盘弹出、系统导航栏隐藏显示均会触发这里
//                int heightRoot = content.getRootView().getHeight();//包含虚拟按键的高度(如果有的话)int heightDecor = content.getHeight();//不含虚拟按键的高度,包含状态栏高度
//                Log.e("SoftKeyboardFi", "heightDecor  " + heightDecor);int usableHeight = computeUsableHeight();//我们setContentView设置的view的可用高度if (usableHeight != lastUsableHeight) {lastUsableHeight = usableHeight;//防止重复变动int heightDifference = heightDecor - usableHeight;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && activity.isInMultiWindowMode()) {//如果是分屏模式if (heightDifference > 0) {//分屏模式,只要变动了就人为弹出键盘,因为分屏可能该Activity是在手机屏幕的上方,弹出输入法只是遮盖了一丁点~如果不合适,需要你自己适配了!setHeight(heightDecor - heightDifference); //这里不能加状态栏高度哟~} else {setHeight(FrameLayout.LayoutParams.MATCH_PARENT);//还原默认高度,不能用计算的值,因为虚拟导航栏显示或者隐藏的时候也会改变高度}} else {if (heightDifference > (heightDecor / 4)) {//高度变动超过decor的四分之一则认为是软键盘弹出事件,为什么不用屏幕高度呢?开始以为这样在分屏模式下也可以监听,但是实测不行。Log.e("SoftKeyboardFi", "heightDifference > (heightDecor / 4) true");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {setHeight(heightDecor - heightDifference + barStatusHeight);//这里为什么要添加状态栏高度?} else {setHeight(heightDecor - heightDifference);//这里不添加状态栏高度?不懂为什么,原版如此,就先这样吧。遇到再说~}if (null != AppFloatView.instance) {if (AppFloatView.get().appFloatIsShow()) {AppFloatView.get().hideFloat();}}} else {Log.e("SoftKeyboardFi", "heightDifference > (heightDecor / 4) false");setHeight(FrameLayout.LayoutParams.MATCH_PARENT);//还原默认高度,不能用计算的值,因为虚拟导航栏显示或者隐藏的时候也会改变高度if (null != AppFloatView.instance) {if (!AppFloatView.get().appFloatIsShow() && !AppFloatView.IS_HIDE_LAYOUT) {AppFloatView.get().showFloat();}}}}}}});}private void setHeight(int height) {if (mFrameLayoutParams.height != height) {// 不必要的更新就不要了mContentView.postDelayed(() -> {// 键盘弹起uni已经更新了,就不用再次更新// uni 没更新,不更新,所以搞个延迟更新布局if (mFrameLayoutParams.height != height) {mFrameLayoutParams.height = height;mContentView.requestLayout();// 触发布局更新}}, 20);}}private int computeUsableHeight() {Rect r = new Rect();mContentView.getWindowVisibleDisplayFrame(r);// 全屏模式下:直接返回r.bottom,r.top其实是状态栏的高度return (r.bottom - r.top);}private int computeUsableWidth() {Rect r = new Rect();mContentView.getWindowVisibleDisplayFrame(r);// 全屏模式下:直接返回r.bottom,r.top其实是状态栏的高度//横屏就是宽度return (r.right - r.left);}//下面相关代码来自:https://github.com/yy1300326388/AndroidBarUtils/blob/master/app/src/main/java/cn/zsl/androidbarutils/utils/AndroidBarUtils.java//完整代码,全屏时有问题。private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";/*** 获取状态栏高度** @param context context* @return 状态栏高度*/private static int getStatusBarHeight(Activity context) {// 获得状态栏高度return getBarHeight(context, STATUS_BAR_HEIGHT_RES_NAME);}/*** 获取导航栏高度** @param activity activity* @return 导航栏高度*/private static int getNavigationBarHeight(Activity activity) {if (hasNavBar(activity)) {// 获得导航栏高度return getBarHeight(activity, NAV_BAR_HEIGHT_RES_NAME);} else {return 0;}}/*** 获取横屏状态下导航栏的宽度** @param activity activity* @return 导航栏的宽度*/private static int getNavigationBarWidth(Activity activity) {if (hasNavBar(activity)) {// 获得导航栏高度return getBarHeight(activity, NAV_BAR_WIDTH_RES_NAME);} else {return 0;}}/*** 获取Bar高度** @param context context* @param barName 名称* @return Bar高度*/private static int getBarHeight(Context context, String barName) {// 获得状态栏高度int resourceId = context.getResources().getIdentifier(barName, "dimen", "android");return context.getResources().getDimensionPixelSize(resourceId);}/*** 是否有NavigationBar** @param activity 上下文* @return 是否有NavigationBar*/private static boolean hasNavBar(Activity activity) {WindowManager windowManager = activity.getWindowManager();Display d = windowManager.getDefaultDisplay();DisplayMetrics realDisplayMetrics = new DisplayMetrics();if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {d.getRealMetrics(realDisplayMetrics);}int realHeight = realDisplayMetrics.heightPixels;int realWidth = realDisplayMetrics.widthPixels;DisplayMetrics displayMetrics = new DisplayMetrics();d.getMetrics(displayMetrics);int displayHeight = displayMetrics.heightPixels;int displayWidth = displayMetrics.widthPixels;return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;}
}

参考这篇文章,详细请参考:https://blog.csdn.net/passerby_b/article/details/82686662

Android uni app原生插件页面全屏Activity的键盘档住输入框或弹起键盘跳动问题相关推荐

  1. uniapp APP项目启动页面全屏显示去除导航栏和下巴

    uniapp APP项目启动页面全屏显示去除导航栏和下巴 <template><view><!-- 启动图 --><view class="star ...

  2. html5页面可见xing,【 前端资源 网页插件 】全屏滚动效果H5FullscreenPage.js

    前提: 介于现在很多活动都使用了 类似全屏滚动效果 尤其在微信里面 我自己开发了一个快速构建 此类项目的控件 与市面上大部分控件不同的是此控件还支持元素的动画效果 并提供多种元素效果 基于zepto. ...

  3. Android uni-app 封装原生插件

    前言 据广大用户的需求,需要把我们anyRTC的SDK,封装到uni-app来使用,并且实现音视频通话.这边文章图文讲解一下怎么封装原生插件,并且在下一章uni-app实现音视频通话. anyRTC开 ...

  4. android 点击图片动画效果,Android仿微信图片点击全屏效果

    废话不多说,先看下Android图片点击全屏效果: 先是微信的 再是模仿的 先说下实现原理,再一步步分析 这里总共有2个Activity一个就是主页,一个就是显示我们图片效果的页面,参数通过Inten ...

  5. android 代码设置dialog 全屏,Android里把Dialog设置为全屏的方法

    Android里把Dialog设置为全屏的方法 有的时候我们需要把Dialog设置为全屏,于是我们想到了如下的办法: //设置成全屏 LinearLayout.LayoutParams p = new ...

  6. android自定义播放器按钮,android – 使用exo播放器添加全屏视频按钮

    如果您使用的是SimpleExoPlayerView,则可以自定义播放器的视图,尤其是Control的视图.查看SimpleExoPlayerView的文档: Attributes The follo ...

  7. vue实现页面全屏和退出全屏

    pc端使用vue实现页面全屏和退出全屏 element.requestFullScreen() -- 全屏显示 Element.requestFullscreen()方法用于 异步请求使得Elemen ...

  8. HTML期末大作业—— 游戏网页(5个页面) ~ 全屏游戏美术大赛作品征集网页 HTML+CSS+JS ~ web课程设计网页规划与设计

    HTML期末大作业-- 游戏网页(5个页面) ~ 全屏游戏美术大赛作品征集网页 HTML+CSS+JS ~ web课程设计网页规划与设计 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感 ...

  9. HTML期末大作业—— 游戏网页(5个页面) ~ 全屏游戏美术大赛作品征集网页 HTML+CSS+JS ~ web课程设计网页规划与设计...

    HTML期末大作业-- 游戏网页(5个页面) ~ 全屏游戏美术大赛作品征集网页 HTML+CSS+JS ~ web课程设计网页规划与设计 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感 ...

  10. Android 点击图片放大至全屏 再次点击关闭过度动画 Shared Element效果(共享元素效果)

    Android 点击图片放大至全屏 再次点击关闭过度动画 最近项目需要给用户一个体验优化,各种查阅,然后改了很多地方,类似于图片的点击预览,消息列表的点击流畅过渡. Shared Element效果( ...

最新文章

  1. springMVC实现文件下载(附带Servlet方式)
  2. java进程和线程_Java™ 教程(进程和线程)
  3. BootStrapJS——modal弹出框
  4. 热式气体质量流量计检定规程_宁夏热式气体质量流量计价位,玻璃管液位计怎么样...
  5. python如何写二进制乘法_使用python写乘法口诀表
  6. json 文档拆分工具_如何把PDF多页文档拆为单页?快看高手私藏实用的技巧
  7. ros开发增加clion常用模板及初始化配置(四)
  8. SharePoint【学习笔记】-- SPWeb.EnsureUser()注意AllowUnsafeUpdates=true
  9. 《zabbix_agent客户端的添加》-5
  10. 第2章:知识表示--实践:Protégé本体构建
  11. linux编译webengine,am3352请问如何在linux3.8上移植带有webengine的qt5?
  12. 【渝粤题库】陕西师范大学 《道德教育案例研究》作业
  13. 问题 C: 神奇的口袋
  14. html导航栏的颜色怎么改变,我怎样才能改变导航栏的背景颜色
  15. 大数据技术之Spark Streaming概述
  16. 泰坦尼克号预测python_kaggle:泰坦尼克号获救预测_Titanic_EDA##
  17. java课程结课论文,语言课程论文范文
  18. 「订单」业务的设计与实现
  19. 【算法】Catalan数
  20. Excel-VBA操作文件四大方法之一(转)

热门文章

  1. 千锋python培训机构可靠吗
  2. 不想在网易博客写技术文章了
  3. 如何将eclipse项目和svn关联(从服务器取项目)
  4. 如何查看hadoop集群的四个配置文件(core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml )
  5. javaFX 学习之 超链接(HyperLink) 转载
  6. python wgs84坐标转换_python WGS84和ECEF坐标的转换
  7. 什么是瀑布图_什么是瀑布图以及为什么我需要一个
  8. Teredo Tunnel Adapter: Error Code 10
  9. 如何检查你的MAC是不是原封正品
  10. 【设计图交接与沟通的高效平台】上海道宁为设计师与开发者提供产品团队的互联空间——Zeplin