在做菠菜源码搭建 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));
}
原文地址:http://blog.51cto.com/13926356/2160764
时间: 2024-11-05 17:24:18