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

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

注意!本代码并不能适配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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容