神马笔记录音功能采用PopupWindow
作为容器实现录音编辑器功能,在适配刘海屏时出现了定位问题。
一、目标
在荣耀畅玩7上,显示一切正常,完美定位。
二、刘海屏问题
完全相同的代码,在红米6Pro上出现了问题。
只有在打开“隐藏屏幕刘海”和采用“经典导航键”时,相当于关闭了所谓“全面屏”功能后,界面显示是正常的。
隐藏屏幕刘海 | 系统导航方式 | 截图 |
---|---|---|
关闭 | 全面屏手势 | |
关闭 | 经典导航键 | |
打开 | 全面屏手势 | |
打开 | 经典导航键 |
三、问题分析
1. 实现思路
控件采用右下对齐方式,通过设置paddingBottom
实现对齐到anchor。
2. 实现代码
int getPaddingBottom(View anchor) {
int y;
int bottom;
View rootView = anchor.getRootView();
// root view relative to display
{
DisplayMetrics dm = this.displayMetrics;
Display d = context.getWindowManager().getDefaultDisplay();
d.getMetrics(dm);
// d.getRealMetrics(dm); // must consider navigation bar
int realHeight = dm.heightPixels;
Rect visibleDisplayFrame = this.bounds;
rootView.getWindowVisibleDisplayFrame(visibleDisplayFrame);
y = realHeight - visibleDisplayFrame.bottom;
bottom = visibleDisplayFrame.bottom;
}
// anchor relative to root
if (rootView instanceof ViewGroup) {
Rect anchorRect = this.bounds;
anchorRect.set(0, 0, anchor.getWidth(), anchor.getHeight());
((ViewGroup)rootView).offsetDescendantRectToMyCoords(anchor, anchorRect);
int offset = (bottom - anchorRect.bottom);
y += offset;
}
return y;
}
3. 问题所在
paddingBottom
的计算分成2步
- 计算根控件的paddingBottom
- 计算anchor与根控件的paddingBottom
2个步骤的计算都可能存在问题。
Display
提供了2个接口,getMetrics
和getRealMetrics
,非全面屏必须使用getMetrics
接口获取的才是去掉导航条的高度。
其次,anchor与根控件的paddingBottom的计算也可能存在问题。
虽然通过offsetDescendantRectToMyCoords
计算出anchor相对于根控件的位置,但根控件的高度是多少,并无法明确确定。
四、解决方案
采用paddingTop的方案。
paddingTop方案能准确计算出相对位置,问题是必须首先明确自身的高度才可能。
采用固定控件高度的方式来实现。
int getPaddingTop(View anchor) {
int y = 0;
View rootView = anchor.getRootView();
// anchor relative to root
if (rootView instanceof ViewGroup) {
Rect anchorRect = this.bounds;
anchorRect.set(0, 0, anchor.getWidth(), anchor.getHeight());
((ViewGroup)rootView).offsetDescendantRectToMyCoords(anchor, anchorRect);
y = anchorRect.bottom;
}
if (y > 0) {
int height = context.getResources().getDimensionPixelSize(R.dimen.tapeActionHeight);
y -= height;
y -= this.statusBarHeight;
}
y = y < 0? 0: y;
return y;
}
五、遗留问题
相较于paddingTop方案,更喜欢paddingBottom的方案。
使用paddingBottom可以不用固化控件高度,更加自由一些。
未来再针对刘海屏、水滴屏进行更多测试,希望能改回paddingBottom方案。
六、接下来
继续测试,正确明天7月1日发布2.7.0的正式版本。
七、Finally
尔时世尊。食时。
著衣持钵。入舍卫大城乞食。
于其城中。次第乞已。还至本处。
饭食讫。
收衣钵。
洗足已。
敷座而坐。