美文网首页
关于华为虚拟返回键盘的适配

关于华为虚拟返回键盘的适配

作者: XINHAO_HAN | 来源:发表于2017-07-26 14:09 被阅读0次

    我们一般都知道如果你使用沉浸式状态栏,底下的华为键盘会挡住你的布局

    注意!本代码并不能适配popupWindow(没尝试过在popupWindow适配过,但有一点popupWindow是在某个控件底下显示,而且按照Android的作风,应该是可以适配的,需要亲们的合理尝试)

    第一种是从互联网找到的,(有个毛病,总是空那么一点点,强迫症表示忍受不了~~~~)

    第二种是根据改进的

    第一种代码(互联网的,):

    
    public class AndroidBug54971Workaround {
    
        public static void assistActivity(View content) {
            new AndroidBug54971Workaround(content);
        }
    
        private View mChildOfContent;
        private int usableHeightPrevious;
        private ViewGroup.LayoutParams frameLayoutParams;
    
        private AndroidBug54971Workaround(View content) {
            mChildOfContent = content;
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                public void onGlobalLayout() {
                    possiblyResizeChildOfContent();
                }
            });
            frameLayoutParams = mChildOfContent.getLayoutParams();
        }
    
        private void possiblyResizeChildOfContent() {
            int usableHeightNow = computeUsableHeight();
            if (usableHeightNow != usableHeightPrevious) {
                //如果两次高度不一致
    
                //将计算的可视高度设置成视图的高度
                frameLayoutParams.height = usableHeightNow;
                mChildOfContent.requestLayout();//请求重新布局
                usableHeightPrevious = usableHeightNow;
            }
        }
    
        private int computeUsableHeight() {
            //计算视图可视高度
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            Log.e("高度计算:", "computeUsableHeight: " + (r.bottom - r.top));
            return (r.bottom - r.top);
        }
    

    使用是这样的

            AndroidBug54971Workaround.assistActivity(View.inflate(UIUtils.getContext(), findViewById(android.R.id.content));
    

    我不理解的是他说了这样一句话,但有一点,我换成我的布局之后,我费了死活的劲还是有空白,底部总是有空白的地方

    如果你看的懂代码,你肯定知道assistActivity方法里放入的View是你 要调整高度的视图。
    

    填:R.id.content,别填你的根布局

    给大家补充一点知识:R.id.content是根布局,就是你每写一个页面,系统都会给你自动加一个R.id.content根布局,所以我们只要更改这个根布局高度就可以了

     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewTreeObserver android.view.View.getViewTreeObserver()' on a null object reference
    

    ,所以说你必须填个这个玩意:android.R.id.content(PS:我的是Fragment所以我的这个是能运行,但有空白)
    这个玩意的用意是:

    1.在安卓布局文件中添加控件<Fragment />,
    2.系统定义的此Fragment的id为android.R.id.content
    3.所以调用findViewById(android.R.id.content)可以得到此Fragment的view。
    
            AndroidBug54971Workaround.assistActivity(View.inflate(UIUtils.getContext(), R.layout.activity_base_fragment, null));
    

    更改效果---------------------------------------------------------

    思路:获取屏幕高度,屏幕高度怎样获取?

    我简单给大家说一下观念
    
    每个Activity它都有一个对应的Window,而每个Window都有对应的一WindowManager
    
    启动Activity的时候会默认创建一个Window和WindowManager,并且在WindowManager里边的宽高都是和屏幕一样的,这就是为什么你看到的每个Activity都是全屏的
    

    代码:

    //获取屏幕高度

       //获取屏幕高度,这里的Context一定要是Activity的Context,--Application所继承下来的Context并没有样式和Window,WindowManager,,会报错
    
        public static int getScreenHeight(Context context) {
            WindowManager wm = (WindowManager) context
                    .getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics outMetrics = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(outMetrics);
            return outMetrics.heightPixels;
        }
    

    //所有代码

    
    
    /**
     * XINHAO_HAN适配类,适配底部虚拟键盘
     */
    
    public class AndroidViews_hxh {
    
        public static void assistActivity(View content, Context context) {
            new AndroidViews_hxh(content, context);
        }
    
        private View mChildOfContent;
        private int usableHeightPrevious;
        private ViewGroup.LayoutParams frameLayoutParams;
    
        private AndroidViews_hxh(View content, Context context) {
            mChildOfContent = content;
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                public void onGlobalLayout() {
                    possiblyResizeChildOfContent(context);
                }
            });
            frameLayoutParams = mChildOfContent.getLayoutParams();
        }
    
        private void possiblyResizeChildOfContent(Context context) {
            int usableHeightNow = computeUsableHeight(context);
            if (usableHeightNow != usableHeightPrevious) {
                //如果两次高度不一致
                //将计算的可视高度设置成视图的高度
                frameLayoutParams.height = usableHeightNow;
                mChildOfContent.requestLayout();//请求重新布局
                usableHeightPrevious = usableHeightNow;
            }
        }
    
        private int computeUsableHeight(Context context) {
           /* //计算视图可视高度
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            Log.e("高度计算:", "computeUsableHeight: " + (r.bottom - r.top));
            Log.e("高度计算:", "低: " + (r.top));
            Log.e("高度计算:", "顶: " + (r.bottom));*/
    
            //获取屏幕高度
            int screenHeight = getScreenHeight(context);
            //获取键盘高度
            int bottomStatusHeight = getBottomStatusHeight(context);
    
            return screenHeight - (bottomStatusHeight / 2);
        }
    
    
        //获取屏幕原始尺寸高度,包括虚拟功能键高度
        public static int getDpi(Context context) {
            int dpi = 0;
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();
            DisplayMetrics displayMetrics = new DisplayMetrics();
            @SuppressWarnings("rawtypes")
            Class c;
            try {
                c = Class.forName("android.view.Display");
                @SuppressWarnings("unchecked")
                Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
                method.invoke(display, displayMetrics);
                dpi = displayMetrics.heightPixels;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return dpi;
        }
    
    
        //获取键盘高度
        public static int getBottomStatusHeight(Context context) {
            int totalHeight = getDpi(context);
    
            int contentHeight = getScreenHeight(context);
    
            return totalHeight - contentHeight;
        }
    
        //获取屏幕高度
    
        public static int getScreenHeight(Context context) {
            WindowManager wm = (WindowManager) context
                    .getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics outMetrics = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(outMetrics);
            return outMetrics.heightPixels;
        }
    
    }
    

    PS:如果觉得好玩,做成华为的那种,你只需要给View价格动画就OK了.

    使用:在 setContentView(R.layout.activity_base_fragment);后边加一句

     /**
             *
             * @View 填写View
             *
             * @Context 填写上下文
             *
             * */
    AndroidViews_hxh.assistActivity(findViewById(android.R.id.content), this);
    

    HUAWEI全机型适配效果------------------(因为没办法公司没有别的有虚拟按键的手机,啊......只有华为的.....)

    package com.jiuhong.boyuan.view;
    
    import android.content.Context;
    import android.graphics.Rect;
    import android.util.DisplayMetrics;
    import android.util.Log;
    import android.view.Display;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewTreeObserver;
    import android.view.WindowManager;
    
    import java.lang.reflect.Method;
    
    /**
     * XINHAO_HAN适配类,适配底部虚拟键盘
     */
    
    public class AndroidViews_hxh {
    
        public static void assistActivity(View content, Context context) {
            new AndroidViews_hxh(content, context);
        }
    
        private View mChildOfContent;
        private int usableHeightPrevious;
        private ViewGroup.LayoutParams frameLayoutParams;
    
        private AndroidViews_hxh(View content, Context context) {
            mChildOfContent = content;
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                public void onGlobalLayout() {
                    possiblyResizeChildOfContent(context);
                }
            });
            frameLayoutParams = mChildOfContent.getLayoutParams();
        }
    
        private void possiblyResizeChildOfContent(Context context) {
            int usableHeightNow = computeUsableHeight(context);
            if (usableHeightNow != usableHeightPrevious) {
                //如果两次高度不一致
                //将计算的可视高度设置成视图的高度
                frameLayoutParams.height = usableHeightNow;
                mChildOfContent.requestLayout();//请求重新布局
                usableHeightPrevious = usableHeightNow;
            }
        }
    
        private int computeUsableHeight(Context context) {
           /* //计算视图可视高度
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            Log.e("高度计算:", "computeUsableHeight: " + (r.bottom - r.top));
            Log.e("高度计算:", "低: " + (r.top));
            Log.e("高度计算:", "顶: " + (r.bottom));*/
    
            //获取屏幕高度
            int screenHeight = getScreenHeight(context);
            //获取键盘高度
            int bottomStatusHeight = getBottomStatusHeight(context);
    
            Log.e("高度计算:", "键盘高度: " + bottomStatusHeight );
            Log.e("高度计算:", "获取屏幕高度: " + screenHeight );
            Log.e("高度计算:", "最终高度: " + (screenHeight - (bottomStatusHeight / 2)) );
            return screenHeight;
        }
    
    
        //获取屏幕原始尺寸高度,包括虚拟功能键高度
        public static int getDpi(Context context) {
            int dpi = 0;
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();
            DisplayMetrics displayMetrics = new DisplayMetrics();
            @SuppressWarnings("rawtypes")
            Class c;
            try {
                c = Class.forName("android.view.Display");
                @SuppressWarnings("unchecked")
                Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
                method.invoke(display, displayMetrics);
                dpi = displayMetrics.heightPixels;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return dpi;
        }
    
    
        //获取键盘高度
        public static int getBottomStatusHeight(Context context) {
            int totalHeight = getDpi(context);
    
            int contentHeight = getScreenHeight(context);
    
            return totalHeight - contentHeight;
        }
    
        //获取屏幕高度
    
        public static int getScreenHeight(Context context) {
            WindowManager wm = (WindowManager) context
                    .getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics outMetrics = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(outMetrics);
            return outMetrics.heightPixels;
        }
    
    }
    
    

    运行效果图---------------------------------------------------<代码版本为:HUAWEI全机型适配效果>

    录像-2017-07-26-14-53-27_20170726150238.gif

    0.0

    相关文章

      网友评论

          本文标题:关于华为虚拟返回键盘的适配

          本文链接:https://www.haomeiwen.com/subject/cubnkxtx.html