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

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

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

猜你喜欢

转载自blog.csdn.net/qq_31392539/article/details/93720926