android适配华为菠菜源码搭建虚拟键

在做菠菜源码搭建 dsluntan.com VX:17061863513横竖屏展示时,发现网上适配虚拟键代码没有做横屏状态下适配,导致横屏状态下,底部虚拟键遮挡了布局内容。

所以横屏状态下也需要适配华为虚拟键。只需要在content布局改变时,同时记录当前可用的视图宽度,重新请求布局即可。下面是代码:

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import java.lang.reflect.Method;

public class NavigationBarUtil {

private static NavigationBarUtil Instance;

public static NavigationBarUtil getInstance() {
    return Instance = new NavigationBarUtil();
}

public void initActivity(View content) {
    mObserved = content;
    //给View添加全局的布局监听器监听视图的变化
    mObserved.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        public void onGlobalLayout() {
            resetViewHeight();
        }
    });
    layoutParams = mObserved.getLayoutParams();
}

private View mObserved;//被监听的视图
private int usableHeightView;//视图变化前的可用高度
private int usableWidthView;//视图变化前的可用宽度
private ViewGroup.LayoutParams layoutParams;

private NavigationBarUtil() {
}

/**
 * 重置视图的高度,使不被底部虚拟键遮挡
 */
private void resetViewHeight() {
    int usableHeightViewNow = CalculateAvailableHeight();
    int usableWidthViewNow = CalculateAvailableWidth();
    //比较布局变化前后的View的可用高度
    if (usableHeightViewNow != usableHeightView) {
        //如果两次高度不一致
        //将当前的View的可用高度设置成View的实际高度
        layoutParams.height = usableHeightViewNow;
        mObserved.requestLayout();//请求重新布局
        usableHeightView = usableHeightViewNow;
    }
    if (usableWidthViewNow != usableWidthView) {
        layoutParams.width = usableWidthViewNow;
        mObserved.requestLayout();//请求重新布局
        usableWidthView = usableWidthViewNow;
    }
}

/**
 * 计算视图的宽度
 * @return
 */
private int CalculateAvailableWidth() {
    Rect r = new Rect();
    mObserved.getWindowVisibleDisplayFrame(r);
    return (r.right);
}

/**
 * 计算视图的高度
 *
 * @return
 */
private int CalculateAvailableHeight() {
    Rect r = new Rect();
    mObserved.getWindowVisibleDisplayFrame(r);

// return (r.bottom - r.top);//如果不是沉浸状态栏,需要减去顶部高度
return (r.bottom);//如果是沉浸状态栏
}

/**
 * 判断底部是否有虚拟键
 *
 * @param context
 * @return
 */
public boolean hasNavigationBar(Context context) {
    boolean hasNavigationBar = false;
    Resources rs = context.getResources();
    int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
    if (id > 0) {
        hasNavigationBar = rs.getBoolean(id);
    }
    try {
        Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
        Method m = systemPropertiesClass.getMethod("get", String.class);
        String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
        if ("1".equals(navBarOverride)) {
            hasNavigationBar = false;
        } else if ("0".equals(navBarOverride)) {
            hasNavigationBar = true;
        }
    } catch (Exception e) {

    }
    return hasNavigationBar;

}

}
调用方式:在抽取的Activity基类中setContentView()方法后调用

    //适配华为部分机型虚拟键
    if (NavigationBarUtil.getInstance().hasNavigationBar(this)) {
        NavigationBarUtil.getInstance().initActivity(findViewById(android.R.id.content));
    }

猜你喜欢

转载自blog.51cto.com/13926356/2160764