文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

鸿蒙输入框被软键盘遮挡的解决办法

2024-12-03 02:28

关注

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

处理前后对比
 

问题现状

安卓上面,输入框被软键盘遮挡,很简单

  1. xml 配置 
  2. android:windowSoftInputMode="adjustPan" 
  3. 或者,java 配置 
  4. getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); 

 这样,软键盘弹出后,输入框就会自动上移。

鸿蒙上也有类似的设置,但是貌似没效果:

  1. getWindow().setInputPanelDisplayType(WindowManager.LayoutConfig.INPUT_ADJUST_PAN); 

解决过程

原理:

布局文件用ScrollView包起来

监听根布局大小变化,变小了,证明输入法弹出了。

滚动ScrollView,使当前焦点控件显示在软键盘上方。

核心代码:

  1. public class MainAbilitySlice extends AbilitySlice { 
  2.     private EventHandler mainHandler = new EventHandler(EventRunner.getMainEventRunner()); 
  3.     private MyTask myTask = null
  4.     class MyTask implements Runnable { 
  5.         private final int softHeight; 
  6.         private final ScrollView root; 
  7.         private final Rect decorRect; 
  8.  
  9.         public MyTask(int softHeight, ScrollView root, Rect decorRect) { 
  10.             this.softHeight = softHeight; 
  11.             this.root = root; 
  12.             this.decorRect = decorRect; 
  13.         } 
  14.  
  15.         @Override 
  16.         public void run() { 
  17.             Timber.d("onRefreshed() called with: softHeight = [ %s ]", softHeight); 
  18.             Component focusView = root.findFocus(); 
  19.             int focusTop = focusView.getLocationOnScreen()[1];//焦点控件的左上角 
  20.             root.fluentScrollByY(focusTop + focusView.getHeight() - decorRect.top - decorRect.getHeight() + 100); 
  21.         } 
  22.     } 
  23.  
  24.     @Override 
  25.     public void onStart(Intent intent) { 
  26.         super.onStart(intent); 
  27.         getWindow().setInputPanelDisplayType(WindowManager.LayoutConfig.INPUT_ADJUST_PAN); 
  28.         super.setUIContent(ResourceTable.Layout_ability_main); 
  29.  
  30.         Optional display = DisplayManager.getInstance().getDefaultDisplay(getContext()); 
  31.         Point pt = new Point(); 
  32.         display.get().getSize(pt); 
  33.         int screenHeight = pt.getPointYToInt();//不包括状态栏(手机时间、wifi显示的那一部分,) 2211,状态栏是129,加起来就是2340 
  34.         Timber.d("onRefreshed() called with: screenHeight = [ %s ]", screenHeight); 
  35.  
  36.         ScrollView root = (ScrollView) findComponentById(ResourceTable.Id_root); 
  37.         root.setLayoutRefreshedListener(new Component.LayoutRefreshedListener() { 
  38.             @Override 
  39.             public void onRefreshed(Component component) { 
  40.                 //包括栏,但不包括状态栏。默认 大小 (0,129,1080,2340),top=129即状态栏 , height=2211。 同android的decorView 
  41.                 Rect decorRect = new Rect(); 
  42.                 component.getWindowVisibleRect(decorRect); 
  43.                 Timber.d("onRefreshed() called with: rect = [ %s ]", decorRect); 
  44.                 if (decorRect.getHeight() == 0) { 
  45.                     //刚进入界面可能为0 
  46.                     return
  47.                 } 
  48.                 int softHeight = screenHeight - decorRect.getHeight(); 
  49.                 Timber.d("onRefreshed() called with: softHeight = [ %s ]", softHeight); 
  50.  
  51.                 if (softHeight > 100) {//当输入法高度大于100判定为输入法打开了 
  52.                     if (myTask != null) { 
  53.                         mainHandler.removeTask(myTask); 
  54.                         myTask = null
  55.                     } 
  56.                     mainHandler.postTask(myTask = new MyTask(softHeight, root, decorRect), 100); 
  57.                 } 
  58.             } 
  59.         }); 
  60.     } 

 完整代码见文末 

特别说明: 滚动操作为什么要delay 100毫秒?因为点击一个输入框Component.LayoutRefreshedListener有时会反复调用多次,而且间隔时间小于10毫秒,所以会造成滚动距离不准确。用postTask之后,每次调用的时候会把之前的task remove掉,以最新的一次为准。

计算滚动距离

其中上面的大红框是decorRect(即当前Ability可视区域),下面的大黑框是输入法显示区域。其中,软键盘弹出后,输入框被软键盘挡住,图中的小红框。

所以,要滚动的距离就是图中的C=A-B。


可以优化的点:

如果是Dialog中的输入框,当前的计算方法是否正确?

如果不用ScrollView,还有别的解决办法吗?

抽取出工具类或工具方法,代码复用。

文章相关附件可以点击下面的原文链接前往下载

原文链接:https://harmonyos.51cto.com/posts/4776

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯