华为手机7.0以上华为7.0上popwindow位置显示错乱,飘

本文介绍了一个在Android 7.0系统中遇到的问题:PopWindows显示位置偏移,并提供了解决方案。通过检测系统版本并采用特定的方法调整PopWindows的位置,确保其在不同设备上正确显示。

由于测试手机上华为meta8,升级了7.0以后突然popwindows显示位置往上飘了, 其他机型没啥问题,一直没找到原因?后来看到一个连接?

https://code.google.com/p/android/issues/detail?id=221001

原来是 in showAtLocation failed to no gravity 在7.0上没有工作

解决方法是:

   if (android.os.Build.VERSION.SDK_INT >=24) {
                                int[] a = new int[2];
                                v.getLocationInWindow(a);
                                mPopupWindow.showAtLocation(((Activity) context).getWindow().getDecorView(), Gravity.NO_GRAVITY, 0 , a[1]+v.getHeight());
                            } else{
                                mPopupWindow.showAsDropDown(v);
                            }
package com.dubu.rtc.measure; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.PopupWindow; public class KeyBoardHeightHelperOld { private static final String TAG = "KeyBoardHeightHelperOld"; private PopupWindow popwindow; private int start; private static int keyBoardHeight; public void showMeasureWindow(View view, OnMeasureCompleteListener onMeasureCompleteListener) { Log.i(TAG, "showMeasureWindow"); view.post(new Runnable() { @Override public void run() { popwindow = new PopupWindow(); FrameLayout contentView = new MeasureLayout(view.getContext(), new MeasureLayout.onHeightChangedListener() { @Override public void onHeightChanged(int height) { if (start == 0) { start = height; } else if (height < start) { keyBoardHeight = start - height; if (onMeasureCompleteListener != null) { onMeasureCompleteListener.onKeyBoardShow(keyBoardHeight); } } else { if (onMeasureCompleteListener != null) { onMeasureCompleteListener.onKeyBoardHide(); } } } }); popwindow.setContentView(contentView); popwindow.setWidth(100); popwindow.setHeight(WindowManager.LayoutParams.MATCH_PARENT); popwindow.setBackgroundDrawable(new ColorDrawable(Color.RED)); popwindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); popwindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); popwindow.showAtLocation(view.getRootView(), Gravity.NO_GRAVITY, 0, 0); } }); } public void onDetached() { if (popwindow != null) { popwindow.dismiss(); } } public static int getKeyBoardHeight() { return keyBoardHeight; } public interface OnMeasureCompleteListener { void onKeyBoardShow(int keyBoardHeight); void onKeyBoardHide(); } } 这个帮助类中 有些手机键盘弹出键盘的时候 没有获取到键盘高度 怎么解决?
最新发布
07-08
在某些华为设备上,使用 `PopupWindow` 或 `ViewTreeObserver.OnGlobalLayoutListener` 监听软键盘高度时可能会遇到无法正确获取高度的问题。这种现象通常与系统对输入法窗口行为的定制、布局重绘机制优化以及 `PopupWindow` 自身的测量方式有关。 由于部分华为手机未按照标准 Android 流程通知应用窗口插入区域的变化,导致基于 `OnGlobalLayoutListener` 的监听逻辑失效。此外,`PopupWindow` 在测量布局时可能未考虑当前软键盘的状态,使得其返回的高度值不准确 [^2]。 为了解决这一问题,可以采用以下几种方案: ### 使用 `WindowInsetsCompat` 获取软键盘高度 `WindowInsetsCompat` 是 AndroidX 提供的兼容性工具类,能够更可靠地获取包括软键盘在内的窗口插入信息。该方法适用于 Android 4.0 及以上版本,并且能有效避免因设备定制化造成的监听失败问题: ```kotlin import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content)) { view, insets -> val imeHeight = if (insets.isVisible(WindowInsetsCompat.Type.ime())) { insets.getInsets(WindowInsetsCompat.Type.ime()).bottom } else { 0 } // 处理 imeHeight 并更新 UI insets } ``` 此方式不仅提高了兼容性,还能在 `PopupWindow` 中结合使用,确保弹窗内容不会被软键盘遮挡 [^1]。 ### 手动适配 PopupWindow 的软键盘状态 在 `PopupWindow` 显示前,可以通过反射调用系统 API 获取当前软键盘的状态和高度。虽然这种方式依赖于非公开 API,但在特定机型(如华为)上可作为临时解决方案: ```java try { Method method = popupWindow.getClass().getMethod("getInputMethodMode"); int inputMethodMode = (int) method.invoke(popupWindow); // 根据 inputMethodMode 判断是否需要调整弹窗位置 } catch (Exception e) { e.printStackTrace(); } ``` 此外,在显示 `PopupWindow` 时应设置合适的软键盘模式,例如 `setSoftInputMode(PopupWindow.INPUT_METHOD_NEEDED)`,以确保软键盘弹出后视图能正确调整布局 [^3]。 ### 结合定时器轮询检测软键盘状态 在极端情况下,若监听机制仍然不稳定,可考虑使用 `Handler` 定期检查软键盘是否可见,并估算其高度。虽然这种方式效率较低,但能在一定程度上弥补系统行为不一致带来的问题。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值