KitKat FloatingActionButton 有额外的边距
KitKat FloatingActionButton has extra margins
我正在尝试从 FloatingActionButton
展示一个 PopupWindow
因为这是供其他人使用的 SDK 的一部分,我不能依赖于位置或某些属性FloatingActionButton
相反,我必须在 FAB 附近找到一个合适的位置来显示 PopupWindow
我目前有一些代码似乎在 Lollipop 和更新版本上运行良好。当我在 KitKat 上 运行 时,FAB
和 Popup
之间有一些额外的间距。我已经通过对一些偏移量进行硬编码来消除 space,但这是一个非常丑陋的解决方案(并且取决于 FAB
的 elevation
是否与我配置它的方式相同,这也不是可靠的先决条件)
预期外观(适用于 Lollipop):
KitKat 上的错误外观:
首先是我用来显示弹出窗口的代码:
public void onShowPopup(View view) {
View layout = getLayoutInflater().inflate(R.layout.popup_menu, null);
PositionedPopupWindow.withLayout(layout).showRelativeToView(
view,
PositionedPopupWindow.AnchorPoint.values()[spinner.getSelectedItemPosition()],
0, // getResources().getDimensionPixelSize(R.dimen.fab_hmargin),
0 // getResources().getDimensionPixelSize(R.dimen.fab_vmargin)
);
}
我应该能够将 0 传递给最后两个参数,并在 FAB 旁边显示弹出窗口。它在 Lollipop 及更高版本上运行良好,但在 KitKat 上我必须传递一些取决于高度的幻数。
这是showRelativeToView
的正文这是PositionedPopupWindow
的大部分实现
public void showRelativeToView(View parent, AnchorPoint anchorPoint, int hMargin, int vMargin) {
if(anchorPoint == AnchorPoint.Automatic) {
anchorPoint = computeAutomaticAnchorPoint(parent);
}
// Get the size of the popup
getContentView().measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
);
Point popupSize = new Point(getContentView().getMeasuredWidth(), getContentView().getMeasuredHeight());
int gravity = 0, x = 0, y = 0;
// Horizontally align the popup edge closest to the screen edge with the button edge
switch(anchorPoint) {
case TopLeft:
case BottomLeft:
gravity |= Gravity.LEFT;
x += hMargin;
break;
case TopRight:
case BottomRight:
x = -popupSize.x;
x -= hMargin;
gravity |= Gravity.RIGHT;
break;
}
// Vertically align the popup edge closest to the screen edge with the button edge
switch(anchorPoint) {
case TopLeft:
case TopRight:
y = -popupSize.y - parent.getMeasuredHeight();
y += vMargin;
gravity |= Gravity.TOP;
break;
case BottomLeft:
case BottomRight:
// align top of popover and bottom of button
gravity |= Gravity.BOTTOM;
y -= vMargin;
break;
}
PopupWindowCompat.showAsDropDown(this, parent, x, y, gravity);
}
我已经尝试在我的 onCreate
方法中将 FAB 的边距设置为 0,正如其他地方建议的那样,以消除额外的边距,但它似乎没有任何改变。
我的问题是,如果不对幻数进行硬编码(这将无法可靠地工作),我怎样才能摆脱 FAB
和 PopupWindow
之间的额外间距
问题似乎出现了,因为 KitKat 在 FloatingActionButton
周围放置了额外的边距以说明高度阴影,因为这改变了 FAB 的大小,我可以将实际按钮大小与预期大小进行比较,计算必要的偏移量:
public void onShowPopup(View view) {
View layout = getLayoutInflater().inflate(R.layout.popup_menu, null);
int hMargin = 0;
int vMargin = 0;
// Pre-Lollipop the FAB shadow is factored into the button size, KitKat and on the
// shadow isn't part of the button size. By comparing the actual width to the expected
// width we can compute an offset necessary to position the popup adjacent to the FAB
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
hMargin += (int) (view.getWidth() - Util.dpToPixels(this, 56)) / 2;
vMargin += (int) (view.getHeight() - Util.dpToPixels(this, 56)) / 2;
}
PositionedPopupWindow.withLayout(layout).showRelativeToView(
view,
PositionedPopupWindow.AnchorPoint.Automatic,
hMargin,
vMargin
);
}
我正在尝试从 FloatingActionButton
展示一个 PopupWindow
因为这是供其他人使用的 SDK 的一部分,我不能依赖于位置或某些属性FloatingActionButton
相反,我必须在 FAB 附近找到一个合适的位置来显示 PopupWindow
我目前有一些代码似乎在 Lollipop 和更新版本上运行良好。当我在 KitKat 上 运行 时,FAB
和 Popup
之间有一些额外的间距。我已经通过对一些偏移量进行硬编码来消除 space,但这是一个非常丑陋的解决方案(并且取决于 FAB
的 elevation
是否与我配置它的方式相同,这也不是可靠的先决条件)
预期外观(适用于 Lollipop):
KitKat 上的错误外观:
首先是我用来显示弹出窗口的代码:
public void onShowPopup(View view) {
View layout = getLayoutInflater().inflate(R.layout.popup_menu, null);
PositionedPopupWindow.withLayout(layout).showRelativeToView(
view,
PositionedPopupWindow.AnchorPoint.values()[spinner.getSelectedItemPosition()],
0, // getResources().getDimensionPixelSize(R.dimen.fab_hmargin),
0 // getResources().getDimensionPixelSize(R.dimen.fab_vmargin)
);
}
我应该能够将 0 传递给最后两个参数,并在 FAB 旁边显示弹出窗口。它在 Lollipop 及更高版本上运行良好,但在 KitKat 上我必须传递一些取决于高度的幻数。
这是showRelativeToView
的正文这是PositionedPopupWindow
public void showRelativeToView(View parent, AnchorPoint anchorPoint, int hMargin, int vMargin) {
if(anchorPoint == AnchorPoint.Automatic) {
anchorPoint = computeAutomaticAnchorPoint(parent);
}
// Get the size of the popup
getContentView().measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
);
Point popupSize = new Point(getContentView().getMeasuredWidth(), getContentView().getMeasuredHeight());
int gravity = 0, x = 0, y = 0;
// Horizontally align the popup edge closest to the screen edge with the button edge
switch(anchorPoint) {
case TopLeft:
case BottomLeft:
gravity |= Gravity.LEFT;
x += hMargin;
break;
case TopRight:
case BottomRight:
x = -popupSize.x;
x -= hMargin;
gravity |= Gravity.RIGHT;
break;
}
// Vertically align the popup edge closest to the screen edge with the button edge
switch(anchorPoint) {
case TopLeft:
case TopRight:
y = -popupSize.y - parent.getMeasuredHeight();
y += vMargin;
gravity |= Gravity.TOP;
break;
case BottomLeft:
case BottomRight:
// align top of popover and bottom of button
gravity |= Gravity.BOTTOM;
y -= vMargin;
break;
}
PopupWindowCompat.showAsDropDown(this, parent, x, y, gravity);
}
我已经尝试在我的 onCreate
方法中将 FAB 的边距设置为 0,正如其他地方建议的那样,以消除额外的边距,但它似乎没有任何改变。
我的问题是,如果不对幻数进行硬编码(这将无法可靠地工作),我怎样才能摆脱 FAB
和 PopupWindow
之间的额外间距
问题似乎出现了,因为 KitKat 在 FloatingActionButton
周围放置了额外的边距以说明高度阴影,因为这改变了 FAB 的大小,我可以将实际按钮大小与预期大小进行比较,计算必要的偏移量:
public void onShowPopup(View view) {
View layout = getLayoutInflater().inflate(R.layout.popup_menu, null);
int hMargin = 0;
int vMargin = 0;
// Pre-Lollipop the FAB shadow is factored into the button size, KitKat and on the
// shadow isn't part of the button size. By comparing the actual width to the expected
// width we can compute an offset necessary to position the popup adjacent to the FAB
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
hMargin += (int) (view.getWidth() - Util.dpToPixels(this, 56)) / 2;
vMargin += (int) (view.getHeight() - Util.dpToPixels(this, 56)) / 2;
}
PositionedPopupWindow.withLayout(layout).showRelativeToView(
view,
PositionedPopupWindow.AnchorPoint.Automatic,
hMargin,
vMargin
);
}