当前位置: 首页 > 科技观察

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

时间:2023-03-22 15:08:02 科技观察

鸿蒙输入框被软键盘挡住的解决方法框架被软键盘挡住。在xml中配置android:windowSoftInputMode="adjustPan"或者在java中配置getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)都非常简单;这样软键盘弹出后,输入框会自动上移。鸿蒙上也有类似的设置,不过好像没有效果:getWindow().setInputPanelDisplayType(WindowManager.LayoutConfig.INPUT_ADJUST_PAN);解决过程原理:布局文件用ScrollView包裹,监听根布局的大小变化。如果变小,证明输入法弹出了。滚动ScrollView,使当前获得焦点的控件显示在软键盘上方。核心代码:publicclassMainAbilitySliceextendsAbilitySlice{privateEventHandlermainHandler=newEventHandler(EventRunner.getMainEventRunner());privateMyTaskmyTask=null;classMyTaskimplementsRunnable{privatefinalintsoftHeight;privatefinalScrollViewroot;privatefinalRectdecorRect;publicMyTask(intsoftHeight,ScrollViewroot,RectdecorRect){this.softHeight=softHeight;this.root=root;this.decorRect=decorRect;}@Overridepublicvoidrun(){Timber.d("onRefreshed()calledwith:softHeight=[%s]",softHeight);ComponentfocusView=root.findFocus();intfocusTop=focusView.getLocationOnScreen()[1];//焦点控件的左上角root.fluentScrollByY(focusTop+focusView.getHeight()-decorRect.top-decorRect.getHeight()+100);}}@OverridepublicvoidonStart(Intentintent){super.onStart(intent);getWindow().setInputPanelDisplayType(WindowManager.LayoutConfig.INPUT_ADJUST_PAN);super.setUIContent(ResourceTable.Layout_ability_main);Optionaldisplay=DisplayManager.getInstance().getDefaultDisplay(getContext());Pointpt=newPoint();display.get().getSize(pt);intscreenHeight=pt.getPointYToInt();//不包括状态栏(手机时间,wifi显示部分,)2211,status列为129,加起来就是2340Timber.d("onRefreshed()calledwith:screenHeight=[%s]",screenHeight);ScrollViewroot=(ScrollView)findComponentById(ResourceTable.Id_root);root.setLayoutRefreshedListener(newComponent.LayoutRefreshedListener(){@OverridepublicvoidonRefreshed(Componentcomponent){//包含标题栏,但不包含状态栏默认大小(0,129,1080,2340),top=129为状态栏,height=2211。同android的decorViewRectdecorRect=newRect();component.getWindowVisibleRect(decorRect);Timber.d("onRefreshed()calledwith:rect=[%s]",decorRect);if(decorRect.getHeight()==0){//刚进入界面可能是0return;}intsoftHeight=screenHeight-decorRect.getHeight();Timber.d("onRefreshed()calledwith:softHeight=[%s]",softHeight);if(softHeight>100){//当输入法的高度大于100时,判断输入法开启if(myTask!=null){mainHandler.removeTask(myTask);myTask=null;}mainHandler.postTask(myTask=newMyTask(softHeight,root,decorRect),100);}}});}}完整代码见文末特别说明:为什么滚动操作需要延迟100毫秒?因为点击一个输入框Component.LayoutRefreshedListener有时会重复调用多次,而且间隔小于10毫秒,所以滚动距离会不准确。使用postTask后,每次调用都会移除之前的task,以最新的为准。计算滚动距离。上方红色大框为decorRect(即当前Ability可见区域),下方黑色大框为输入法显示区域。其中,软键盘弹出后,输入框被软键盘挡住,如图中小红框所示。因此,滚动的距离为图中的C=A-B。可以优化的点:如果是Dialog中的输入框,当前的计算方式是否正确?如果不用ScrollView,有没有其他解决办法?提取工具类或工具方法并重用代码。文章相关附件可点击下方链接下载原文链接:https://harmonyos.51cto.com/posts/4776更多内容请访问:与华为官方共建的鸿蒙技术社区https:///harmonyos.51cto.com