安卓webview软键盘遮住底部按钮,又名AndroidBug5497

news/2024/11/29 11:54:25/

一、背景介绍
      首先介绍关于adjustSize与adjustpan

        在manifest文件设置activity的windowSoftInputMode设置为 adjustPan 或者adjustResize

       adjustPan会在软键盘弹出的时候平推整个界面,整个界面的大小不变的。缺点: 你编辑的部分会上弹到软键盘上面,但是会造成不可以拖拉,如果编辑的内容下面还有view,你想要操作的话必须先关闭软键盘

      adjustResize则是会调整大小,以便为屏幕上的软键盘腾出空间。但是在全屏/沉浸式状态栏模式下是不可用的

二、解决方式
        安卓提供的adjustResize在全屏模式下不可用,就只能采用其他方式,谷歌上的大神采取的方式是根据app可展示区域的大小动态更改内容的大小,用scrollview包裹住content,这样就可以自己滑动做到不遮挡】

        tips:  根目录必须用ScrollView包裹,不然展示区域变小后无法滑动,相当于没用   另外处理滑动冲突可以采用nestScrollView

       这个代码考虑到了以下几种情况:

        ①有实体底部导航按钮的(oppo r9)  ②没有实体按钮但是开启虚拟底部导航按钮  (三星s8)  ③没有实体按钮但是关闭虚拟底部导航按钮的(红米k30)   ④三的基础上,但是代码运行却反馈有虚拟按钮的(oppo findx)

        (其实难度主要在于如何判断得出底部导航按钮的高度和有无,需要对三星特别处理)

        直接上代码:

   

public class AndroidBug5497Workaround {
 
    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
 
    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }
 
    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    Activity activity;
 
    private AndroidBug5497Workaround(Activity activity) {
        this.activity =activity;
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }
 
 
    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference+ getStatusBarHeight();
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard-getNavigationBarHeight();
            }
            mChildOfContent.setBottom(frameLayoutParams.height);
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }
 
    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }
 
 
    public int getStatusBarHeight(){
        int result = 0;
        int resourceId = ContextUtils.getApplicationContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = ContextUtils.getApplicationContext().getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
 
 
    /**
     * 获取底部虚拟导航栏的高度
     * @return
     */
    public  int getNavigationBarHeight() {
        int height = 0;
        //屏幕实际尺寸
        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getRealMetrics(dm);
        int phoneHeight = dm.heightPixels;
        if (isNavigationBarExist()) {
            Resources resources =activity.getResources();
            int resourceId = resources.getIdentifier("navigation_bar_height",
                    "dimen", "android");
            if (resourceId > 0) {
                //获取NavigationBar的高度
                height = resources.getDimensionPixelSize(resourceId);
            }
        }
        if (height > 0){
            //处理全屏模式下,部分手机isNavigationBarExist()始终返回true,NavigationBar的高度
            int diffValue = (DensityUtils.getScreenHeight(ContextUtils.getApplicationContext()) + height) - phoneHeight;
             //这里对三星特别处理,以为三星机会把状态栏高度算入真正显示高度,
             //不过也可以理解,毕竟我们是全屏模式
            if(!"SAMSUNG".equalsIgnoreCase(Build.MANUFACTURER)){
                diffValue+= getStatusBarHeight();
            }
            if (diffValue > 0){
                height -= diffValue;
            }
        }
        return height;
    }
 
    /**
     * 检测底部虚拟导航栏是否存在
     *有很多教程写通过读取系统参数,无效,因为有些有参数但是不展示
     * @return
     */
    public  boolean isNavigationBarExist(){
        ViewGroup vp = (ViewGroup) activity.getWindow().getDecorView();
        if (vp != null) {
            for (int i = 0; i < vp.getChildCount(); i++) {
                vp.getChildAt(i).getContext().getPackageName();
                if (vp.getChildAt(i).getId() != View.NO_ID
                        && "navigationBarBackground".equals(activity.getResources().getResourceEntryName(vp.getChildAt(i).getId()))) {
                    return true;
                }
            }
        }
        return false;
    }
}
使用方式:   

AndroidBug5497Workaround.assistActivity(你的activity)
 

感谢博主的分享,原文来自:安卓软键盘遮挡输入框+沉浸式+adjustsize失效+适配 (又名5497bug)_只会helloworld的博客-CSDN博客


http://www.ppmy.cn/news/753553.html

相关文章

andriod 软键盘

软键盘显示的原理 软件盘的本质是什么&#xff1f;软键盘其实是一个Dialog。 InputMethodService为我们的输入法创建了一个Dialog&#xff0c;并且将该Dialog的Window的某些参数&#xff08;如Gravity&#xff09;进行了设置&#xff0c;使之能够在底部或者全屏显示。当…

如何在Android手机上更改键盘

There are more keyboard apps available on Android than you’d care to try, but we do recommend trying at least a few of the best keyboard apps to find something you like. When you do, here’s how to get it going on your Android phone. Android上可用的键盘应…

Android 软键盘 相关

获取软键盘状态&#xff1a; // WindowManager.LayoutParams params getWindow().getAttributes(); // if (params.softInputMode WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE) { // // 隐藏软键盘 // getWindow().setSoftInputMode( // WindowManager.LayoutParam…

解决安卓原生键盘遮挡输入框问题

最近在整理之前项目遇到的Bug&#xff0c;整理到一个经常容易遇到的问题&#xff1a;输入框比如短信验证码的输入框点击发送短信时苹果手机弹出的系统键盘会使屏幕弹起&#xff0c;从而不会遮挡输入&#xff0c;但是安卓手机不会。 解决方式&#xff1a;通过navigator.userAge…

Android 输入法键盘使用

Android 输入法键盘使用 一.设置页面输入法展示方式1.adjustXxx2.stateXxx3.代码调用 二.动态调用键盘1.调起键盘2.隐藏键盘 一.设置页面输入法展示方式 我们经常会在项目中遇到输入法展示的情况&#xff0c;有时希望进入页面时自动展示输入法&#xff0c;有时希望页面不展示输…

Android键盘操作

//隐藏键盘/*InputMethodManager imm (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); if(imm.isActive()){imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_NOT_ALWAYS); //imm.showSoftInput(view, 0); //显示软键盘…

Android自定义键盘之汉字键盘

一、软键盘介绍 实现软键盘主要用到了系统的两个类&#xff1a;Keyboard和KeyboardView。 Keyboard类源码的介绍是&#xff1a; Listener for virtual keyboard events.即用于监听虚拟键盘。 KeyboardView类源码的介绍是&#xff1a; A view that renders a virtual {link K…

android软键盘的使用

Android应用开发中&#xff0c;当Activity 中存在EditText 时 进入时往往会弹出软键盘&#xff0c;给用户的体验不好&#xff0c; 如何避免呢&#xff1f; 很简单只需在Activity 声明中加入 android:windowSoftInputMode"adjustResizestateHidden"即可&#xff0c; 以…