700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android 华为虚拟按键适配

android 华为虚拟按键适配

时间:2019-07-10 16:18:05

相关推荐

android 华为虚拟按键适配

为了设置状态栏,会设置透明标签,而华为手机的虚拟按键有可能会遮挡底部导航栏。

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 stubthis.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 visibleframeLayoutParams.height = usableHeightSansKeyboard- heightDifference;} else {// keyboard probably just became hiddenframeLayoutParams.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布局文件代码:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/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>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。