问题描述:
1、在输入任意错误单词,按空格,点击输入词下方的红线(或者长按输入词,点击replace),弹出PopupWindow建议词列表,此时输入词被PopupWindow遮挡。
2、上面所描述的问题在一般情况下是正常的,只有当【输入词太靠手机屏幕下方】或者【改变系统字体大小】时,由于输入词下方的高度无法容纳PopupWindow,导致输入词被遮挡。
解决思路:PopupWindow中字体会随着系统字体大小变动,如此PW的尺寸也会随着变动,所以为了能保持PW在输入词下方,有以下几种解决方案:
1、修改PW尺寸,使其始终小于输入词下方的高度,并使其可以上下滑动。
2、能否让PW显示在输入词以上呢?【这个是我YY的,Google比较强势,只想让她在下面 0_0】。
对于尺寸的修改,修改到多少合适,解决方法各有不同,我的方法是让它的高度=屏幕整体高度-输入词以上的高度,此解决方案会导致一个无伤大雅的小问题,就是当输入词在屏幕顶端时,PW的尺寸太~~~长~~~~ 嗯,就是太长,,PW下面有一部分是空白的,不美丽! 但是总比遮挡了好啊不是么……【最下方有补充】
franemwoks/base/core/java/android/widget/Editor.java
首先定义一个获取系统字体大小的方法:
import java.lang.reflect.InvocationTargetException;
private float getSystemFontScale() {
Configuration mCurConfig = new Configuration();
try {
// 获取ActivityManagerNative类的对象activityManagerNative
Class<?> activityManagerNative = Class
.forName("android.app.ActivityManagerNative");
/*
* 获得可调用getConfiguration方法的对象oam(调用getDefault方法得到的东西)
* getMethod:获取AMN类中的getDefault方法
* invoke:通过activityManagerNative对象调用getDefault方法
*/
Object oam = activityManagerNative.getMethod("getDefault")
.invoke(activityManagerNative);
// 获取getConfiguration方法并通过oam对象调用,得到config对象
Object config = oam.getClass().getMethod("getConfiguration")
.invoke(oam);
mCurConfig.updateFrom((Configuration) config);
// return mCurConfig.fontScale;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mCurConfig.fontScale;
}
在class PinnedPopupWindow中更新PW尺寸
mPopupWindow.update(positionX, positionY, -1, mTextView
.getResources().getDisplayMetrics().heightPixels
- positionY - 30);//减30是为了留点空隙……
在clipVertically(int positionY)中判断系统字体大小,return positionY
if (getSystemFontScale() == 1.15f || getSystemFontScale() == 1.3f) {
Log.d("ran.zhou", "Line 2670, Size = " + getSystemFontScale() + ", positionY = " + positionY);
return positionY;
}
PW滑动的问题,经测试只要变动PW尺寸后就可以了,不过我没有深究,应该是有个地方写好了的,,
此PR原本问题的原因是之前为了解决不能完全显示完PW内容并且无法滑动的问题,修改了clipVertically(int positionY)的return方法,
return Math.min(positionY, displayMetrics.heightPixels - height - 60);
此处-60是不科学的,应该把-60去掉,然后利用文中的方法解决。
更改字体大小会导致PW覆盖输入词的问题,估计Google没有注意到,测试几个机型都存在这个问题,包括我的Nexus5.
20160613更新
以上方法修改后,会导致复制粘贴的弹出窗下方有很长一段空白,代码修改如下:
mPopupWindow.update(positionX, positionY, -1, mTextView
.getResources().getDisplayMetrics().heightPixels
- positionY - 30);
以上代码改成:
int temp = mTextView.getResources().getDisplayMetrics().heightPixels - positionY;
if (this instanceof SuggestionsPopupWindow && (temp < 622)) {
// [BUGFIX]-Add by TCTSH, 2015-11-17,PR-1104959 and PR-885290 Begin
mPopupWindow.update(positionX, positionY, -1, temp - 20);
// [BUGFIX]-Add by TCTSH, 2015-11-17,PR-1104959 and PR-885290 End
}