为了设置状态栏,会设置透明标签,而华为手机的虚拟按键有可能会遮挡底部导航栏。
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ad_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
不要设置FLAG_TRANSLUCENT_NAVIGATION。
由于项目中WebView输入数据,软键盘不会顶上布局,遮盖住页面,使用下边此类解决冲突后出现底部导航栏被遮挡的问题。
/**
* webview-软键盘-冲突
*/
public class KeyBoardListenerManager {
private Activity activity;
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private static KeyBoardListenerManager keyBoardListener;
public static KeyBoardListenerManager newInstance(Activity activity) {
keyBoardListener = new KeyBoardListenerManager(activity);
return keyBoardListener;
}
public KeyBoardListenerManager(Activity activity) {
super();
// TODO Auto-generated constructor stub
this.activity = activity;
}
public void init() {
FrameLayout content = (FrameLayout) activity
.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent
.getLayoutParams();
}
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView()
.getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
frameLayoutParams.height = usableHeightSansKeyboard
- heightDifference;
} else {
// keyboard probably just became hidden
frameLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}
}
调用方式为:KeyBoardListenerManager.newInstance(this).init();
出现华为虚拟按键冲突问题:
解决方案使用下面此类,此类主要作为封装处理特殊手机的工具类。
/**
* 手机操作系统检测
*/
public class PhoneSystemManager {
public static final String SYS_EMUI = "sys_emui";// 华为
public static final String SYS_MIUI = "sys_miui";// 小米
public static final String SYS_FLYME = "sys_flyme";// 魅族
public static final String SYS_NORMAL = "sys_normal";// 一般市面手机
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
private static final String KEY_EMUI_API_LEVEL = "ro.build.hw_emui_api_level";
private static final String KEY_EMUI_VERSION = "ro.build.version.emui";
private static final String KEY_EMUI_CONFIG_HW_SYS_VERSION = "ro.confg.hw_systemversion";
public static String getTelPhoneSystem() {
String SYS = SYS_NORMAL;
try {
Properties prop = new Properties();
prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
if (prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null) {
SYS = SYS_MIUI;//小米
} else if (prop.getProperty(KEY_EMUI_API_LEVEL, null) != null
|| prop.getProperty(KEY_EMUI_VERSION, null) != null
|| prop.getProperty(KEY_EMUI_CONFIG_HW_SYS_VERSION, null) != null) {
SYS = SYS_EMUI;//华为
} else if (getMeizuFlymeOSFlag().toLowerCase().contains("flyme")) {
SYS = SYS_FLYME;//魅族
}
} catch (IOException e) {
e.printStackTrace();
return SYS;
}
return SYS;
}
public static String getMeizuFlymeOSFlag() {
return getSystemProperty("ro.build.display.id", "");
}
private static String getSystemProperty(String key, String defaultValue) {
try {
Class> clz = Class.forName("android.os.SystemProperties");
Method get = clz.getMethod("get", String.class, String.class);
return (String) get.invoke(clz, key, defaultValue);
} catch (Exception e) {
}
return defaultValue;
}
/** 设置透明状态栏目
setMiuiStatusBarDarkMode(this, true);
setMeizuStatusBarDarkIcon(this, true);
**/
public static boolean setMiuiStatusBarDarkMode(Activity activity, boolean darkmode) {
Class extends Window> clazz = activity.getWindow().getClass();
try {
int darkModeFlag = 0;
Class> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean setMeizuStatusBarDarkIcon(Activity activity, boolean dark) {
boolean result = false;
if (activity != null) {
try {
WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
Field darkFlag = WindowManager.LayoutParams.class
.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
Field meizuFlags = WindowManager.LayoutParams.class
.getDeclaredField("meizuFlags");
darkFlag.setAccessible(true);
meizuFlags.setAccessible(true);
int bit = darkFlag.getInt(null);
int value = meizuFlags.getInt(lp);
if (dark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
activity.getWindow().setAttributes(lp);
result = true;
} catch (Exception e) {
}
}
return result;
}
/**
* 处理华为手机虚拟按键和底部导航遮挡问题
* 出现原因-
* getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
* getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
* 加:
* -android::fitsSystemWindows="true"
* 去除-FLAG_TRANSLUCENT_NAVIGATION
* -仍旧不行使用本类-在setContentView(……
* if (AndroidWorkaround.checkDeviceHasNavigationBar(this))
* {
* AndroidWorkaround.assistActivity(findViewById(android.R.id.content));
* }
*
*/
public static class AndroidWorkaround {
public static void assistActivity(View content) {
new AndroidWorkaround(content);
}
private View mChildOfContent;
private int usableHeightPrevious;
private ViewGroup.LayoutParams frameLayoutParams;
private AndroidWorkaround(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);
return (r.bottom);
}
/** 获取虚拟功能键高度 */
public static int getVirtualBarHeigh(Context context) {
int vh = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
try {
@SuppressWarnings("rawtypes")
Class c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, dm);
vh = dm.heightPixels - windowManager.getDefaultDisplay().getHeight();
} catch (Exception e) {
e.printStackTrace();
}
return vh;
}
public static boolean checkDeviceHasNavigationBar(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;
}
}
}
最终得以解决。
请在加载布局文件后使用。
调用方法:
/**
* 虚拟按键-tangZd
*/
private void doSpecialiSomethingAsVirtualBar(){
KeyBoardListenerManager.newInstance(this).init();
if (PhoneSystemManager.AndroidWorkaround.checkDeviceHasNavigationBar(this)) {
PhoneSystemManager.AndroidWorkaround.assistActivity(findViewById(android.R.id.content));
ViewStub stub = (ViewStub) findViewById(R.id.view_stub);
stub.inflate();
View enuiStubView = this.findViewById(R.id.enuiNatView);
LinearLayout.LayoutParams zLayoutParams = (LinearLayout.LayoutParams) enuiStubView.getLayoutParams();
zLayoutParams.height = PhoneSystemManager.AndroidWorkaround.getVirtualBarHeigh(this);
enuiStubView.setLayoutParams(zLayoutParams);
}
}
需要在对应布局的最底部增加布局:
<ViewStub
android:id="@+id/view_stub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/enui_layout"/>
enui_layout布局文件代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@color/black"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/enuiNatView"
android:background="@color/black"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
LinearLayout>