下面列出了android.view.View#getWindowVisibleDisplayFrame ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@SuppressLint("DefaultLocale")
private void showTips(String from, boolean isOpen) {
Point realScreenSize = getRealScreenSize(this);
Point appUsableSize = getAppUsableScreenSize(this);
Point diffSize = getNavigationBarSize(this);
View decorView = getWindow().getDecorView();
Rect frame = new Rect();
decorView.getWindowVisibleDisplayFrame(frame);
mTextTips.setText(String.format("%s:[%s]\n" +
"PanelStatus:[%s]\n" +
"ScreenSize:[%d, %d]\n" +
"UnableSize:[%d, %d]\n" +
"DiffSize:[%d, %d]\n" +
"Visible:[%s, %s]\n",
from, isOpen,
mPanelBoss.isOpen(),
realScreenSize.x, realScreenSize.y,
appUsableSize.x, appUsableSize.y,
diffSize.x, diffSize.y,
frame.left + "-" + frame.right, frame.top + "-" + frame.bottom));
}
/**
* 手机具有底部导航栏时,底部导航栏是否可见
*
* @param activity
* @return
*/
private static boolean isNavigationBarVisible(Activity activity) {
boolean show = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Display display = activity.getWindow().getWindowManager().getDefaultDisplay();
Point point = new Point();
display.getRealSize(point);
View decorView = activity.getWindow().getDecorView();
Configuration conf = activity.getResources().getConfiguration();
if (Configuration.ORIENTATION_LANDSCAPE == conf.orientation) {
View contentView = decorView.findViewById(android.R.id.content);
show = (point.x != contentView.getWidth());
} else {
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
show = (rect.bottom != point.y);
}
}
return show;
}
private int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
final Rect displayFrame = new Rect();
anchor.getWindowVisibleDisplayFrame(displayFrame);
final int[] anchorPos = new int[2];
anchor.getLocationOnScreen(anchorPos);
int bottomEdge = displayFrame.bottom;
if (ignoreBottomDecorations) {
Resources res = anchor.getContext().getResources();
bottomEdge = res.getDisplayMetrics().heightPixels;
}
final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
// anchorPos[1] is distance from anchor to top of screen
int returnedHeight = Math.max(distanceToBottom, distanceToTop);
if (mPopup.getBackground() != null) {
mPopup.getBackground().getPadding(mTempRect);
returnedHeight -= mTempRect.top + mTempRect.bottom;
}
return returnedHeight;
}
private int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
final Rect displayFrame = new Rect();
anchor.getWindowVisibleDisplayFrame(displayFrame);
final int[] anchorPos = new int[2];
anchor.getLocationOnScreen(anchorPos);
int bottomEdge = displayFrame.bottom;
if (ignoreBottomDecorations) {
Resources res = anchor.getContext().getResources();
bottomEdge = res.getDisplayMetrics().heightPixels;
}
final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
// anchorPos[1] is distance from anchor to top of screen
int returnedHeight = Math.max(distanceToBottom, distanceToTop);
if (mPopup.getBackground() != null) {
mPopup.getBackground().getPadding(mTempRect);
returnedHeight -= mTempRect.top + mTempRect.bottom;
}
return returnedHeight;
}
/**
* 手机具有底部导航栏时,底部导航栏是否可见
*/
private static boolean isNavigationBarVisible(Activity activity) {
// View decorView = activity.getWindow().getDecorView();
// return (decorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 2;
boolean show = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Display display = activity.getWindow().getWindowManager().getDefaultDisplay();
Point point = new Point();
display.getRealSize(point);
View decorView = activity.getWindow().getDecorView();
Configuration conf = activity.getResources().getConfiguration();
if (Configuration.ORIENTATION_LANDSCAPE == conf.orientation) {
View contentView = decorView.findViewById(android.R.id.content);
if (contentView != null) {
show = (point.x != contentView.getWidth());
}
} else {
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
show = (rect.bottom != point.y);
}
}
return show;
}
private int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
final Rect displayFrame = new Rect();
anchor.getWindowVisibleDisplayFrame(displayFrame);
final int[] anchorPos = new int[2];
anchor.getLocationOnScreen(anchorPos);
int bottomEdge = displayFrame.bottom;
if (ignoreBottomDecorations) {
Resources res = anchor.getContext().getResources();
bottomEdge = res.getDisplayMetrics().heightPixels;
}
final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
// anchorPos[1] is distance from anchor to top of screen
int returnedHeight = Math.max(distanceToBottom, distanceToTop);
if (mPopup.getBackground() != null) {
mPopup.getBackground().getPadding(mTempRect);
returnedHeight -= mTempRect.top + mTempRect.bottom;
}
return returnedHeight;
}
/**
* 判断虚拟导航栏是否显示
*
* @param context 上下文对象
* @param window 当前窗口
* @return true(显示虚拟导航栏),false(不显示或不支持虚拟导航栏)
*/
public static boolean checkNavigationBarShow(@NonNull Context context, @NonNull Window window) {
boolean show;
Display display = window.getWindowManager().getDefaultDisplay();
Point point = new Point();
display.getRealSize(point);
View decorView = window.getDecorView();
Configuration conf = context.getResources().getConfiguration();
if (Configuration.ORIENTATION_LANDSCAPE == conf.orientation) {
View contentView = decorView.findViewById(android.R.id.content);
show = (point.x != contentView.getWidth());
} else {
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
show = (rect.bottom != point.y);
}
return show;
}
private void calculateChildVisibleBoundsAtEndOfExpansion(
@NonNull View child,
@NonNull FabTransformationSpec spec,
@NonNull MotionTiming translationXTiming,
@NonNull MotionTiming translationYTiming,
float fromX,
float fromY,
float toX,
float toY,
@NonNull RectF childBounds) {
float translationX =
calculateValueOfAnimationAtEndOfExpansion(spec, translationXTiming, fromX, toX);
float translationY =
calculateValueOfAnimationAtEndOfExpansion(spec, translationYTiming, fromY, toY);
// Calculate the window bounds.
Rect window = tmpRect;
child.getWindowVisibleDisplayFrame(window);
RectF windowF = tmpRectF1;
windowF.set(window);
// Calculate the visible bounds of the child given its translation and window bounds.
RectF childVisibleBounds = tmpRectF2;
calculateWindowBounds(child, childVisibleBounds);
childVisibleBounds.offset(translationX, translationY);
childVisibleBounds.intersect(windowF);
childBounds.set(childVisibleBounds);
}
private void updateSpotShadowPosition() {
if (getChildCount() < 1) {
return;
}
final View childView = getChildAt(0);
childView.getWindowVisibleDisplayFrame(mTempRect);
mLightPositionX = mTempRect.width() / 2;
mLightPositionY = 0;
childView.getLocationInWindow(mTmpLocations);
final float zPosition = (mShadowTranslationZ + mShadowElevation);
final float tx = childView.getTranslationX();
final float ty = childView.getTranslationY();
final float positionRelatedTranslationX;
final float positionRelatedTranslationY;
if (mAffectsDisplayedPosition) {
final int childWidth = childView.getWidth();
final int childHeight = childView.getHeight();
final int childCenterPosX = mTmpLocations[0] + (childWidth / 2);
final int childCenterPosY = mTmpLocations[1] + (childHeight / 2);
positionRelatedTranslationX = (float) Math.sqrt((childCenterPosX - mLightPositionX) * mInvDisplayDensity * SPOT_SHADOW_X_TRANSLATION_AMOUNT_COEFFICIENT) * zPosition;
positionRelatedTranslationY = (float) Math.sqrt((childCenterPosY - mLightPositionY) * mInvDisplayDensity * SPOT_SHADOW_Y_TRANSLATION_AMOUNT_COEFFICIENT) * zPosition;
} else {
positionRelatedTranslationX = 0;
positionRelatedTranslationY = mDisplayDensity * NON_POSITION_AWARE_SPOT_SHADOW_Y_TRANSLATION_AMOUNT_COEFFICIENT * zPosition;
}
mSpotShadowTranslationX = (int) (positionRelatedTranslationX + tx + 0.5f);
mSpotShadowTranslationY = (int) (positionRelatedTranslationY + ty + 0.5f);
}
private static int getContentViewInvisibleHeight(final Activity activity) {
final View contentView = activity.findViewById(android.R.id.content);
if (contentView == null) return sContentViewInvisibleHeightPre5497;
final Rect outRect = new Rect();
contentView.getWindowVisibleDisplayFrame(outRect);
Log.d("KeyboardUtils", "getContentViewInvisibleHeight: "
+ (contentView.getBottom() - outRect.bottom));
int delta = Math.abs(contentView.getBottom() - outRect.bottom);
if (delta <= getStatusBarHeight() + getNavBarHeight()) {
return 0;
}
return delta;
}
/**
* 计算 Activity content View 高度
* @param activity {@link Activity}
* @return View 的高度
*/
private static int getContentViewInvisibleHeight(final Activity activity) {
try {
final View contentView = activity.findViewById(android.R.id.content);
Rect rect = new Rect();
contentView.getWindowVisibleDisplayFrame(rect);
return contentView.getRootView().getHeight() - rect.height();
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getContentViewInvisibleHeight");
return 0;
}
}
/**
* @param rootView
* @return b
* 判断键盘弹出状态
*/
private boolean isKeyboardShown(View rootView) {
final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}
private boolean isKeyboardShown(View rootView) {
final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}
public static boolean isKeyboardShowing(Activity activity){
final View decorView = activity.getWindow().getDecorView();
//获取当屏幕内容的高度
int screenHeight = decorView.getHeight();
//获取View可见区域的bottom
Rect rect = new Rect();
// DecorView即为activity的顶级view
decorView.getWindowVisibleDisplayFrame(rect);
//考虑到虚拟导航栏的情况(虚拟导航栏情况下:screenHeight = rect.bottom + 虚拟导航栏高度)
// 选取screenHeight*2/3进行判断
return screenHeight*2/3 > rect.bottom;
}
/**
* Internal helper method to show the cheat sheet toast.
*/
private static boolean showCheatSheet(View view, CharSequence text) {
if (TextUtils.isEmpty(text)) {
return false;
}
final int[] screenPos = new int[2]; // origin is device display
final Rect displayFrame = new Rect(); // includes decorations (e.g. status bar)
view.getLocationOnScreen(screenPos);
view.getWindowVisibleDisplayFrame(displayFrame);
final Context context = view.getContext();
final int viewWidth = view.getWidth();
final int viewHeight = view.getHeight();
final int viewCenterX = screenPos[0] + viewWidth / 2;
final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
final int estimatedToastHeight = (int) (ESTIMATED_TOAST_HEIGHT_DIPS
* context.getResources().getDisplayMetrics().density);
Toast cheatSheet = Toast.makeText(context, text, Toast.LENGTH_SHORT);
boolean showBelow = screenPos[1] < estimatedToastHeight;
if (showBelow) {
// Show below
// Offsets are after decorations (e.g. status bar) are factored in
cheatSheet.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL,
viewCenterX - screenWidth / 2,
screenPos[1] - displayFrame.top + viewHeight);
} else {
// Show above
// Offsets are after decorations (e.g. status bar) are factored in
// NOTE: We can't use Gravity.BOTTOM because when the keyboard is up
// its height isn't factored in.
cheatSheet.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL,
viewCenterX - screenWidth / 2,
screenPos[1] - displayFrame.top - estimatedToastHeight);
}
cheatSheet.show();
return true;
}
/**
* If the soft keyboard is open, this method will close it. Currently only
* works for API 16 and above.
*/
private void closeKeyboardIfOpen()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
final View activityRootView = getWindow().getDecorView().getRootView();
final OnGlobalLayoutListener globalListener = new OnGlobalLayoutListener()
{
@Override
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onGlobalLayout()
{
Rect rect = new Rect();
// rect will be populated with the coordinates of your view that area still visible.
activityRootView.getWindowVisibleDisplayFrame(rect);
int heightDiff = activityRootView.getRootView().getHeight() - (rect.bottom - rect.top);
if (heightDiff > 100)
{
// If the difference is more than 100 pixels, it's probably caused by the soft keyboard being open. Now we want to close it.
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); // Toggle the soft keyboard.
}
// Now we have to remove the OnGlobalLayoutListener, otherwise we will experience errors
activityRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
};
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(globalListener);
}
}
private Point getActionViewCoordinates() {
int[] coordinates = new int[2];
// This method returns a x and y values that can be larger than the dimensions of the device screen.
getLocationOnScreen(coordinates);
// We then need to deduce the offsets
Rect activityFrame = new Rect();
View v = Utils.getActivityContentView(context);
if (v != null) {
v.getWindowVisibleDisplayFrame(activityFrame);
coordinates[0] -= (Utils.getScreenSize(context).x - v.getMeasuredWidth());
coordinates[1] -= (activityFrame.height() + activityFrame.top - v.getMeasuredHeight());
}
return new Point(coordinates[0], coordinates[1]);
}
private static int getContentViewInvisibleHeight(final Activity activity) {
final View contentView = activity.findViewById(android.R.id.content);
Rect outRect = new Rect();
contentView.getWindowVisibleDisplayFrame(outRect);
return contentView.getBottom() - outRect.bottom;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
@Override
public void onGlobalLayout() {
final View userRootView = contentView.getChildAt(0);
final View actionBarOverlayLayout = (View) contentView.getParent();
// Step 1. calculate the current display frame's height.
Rect r = new Rect();
final int displayHeight;
final int notReadyDisplayHeight = -1;
if (isTranslucentStatus) {
// status bar translucent.
// In the case of the Theme is Status-Bar-Translucent, we calculate the keyboard
// state(showing/hiding) and the keyboard height based on assuming that the
// displayHeight includes the height of the status bar.
actionBarOverlayLayout.getWindowVisibleDisplayFrame(r);
final int overlayLayoutDisplayHeight = (r.bottom - r.top);
if (!isOverlayLayoutDisplayHContainStatusBar) {
// in case of the keyboard is hiding, the display height of the
// action-bar-overlay-layout would be possible equal to the screen height.
// and if isOverlayLayoutDisplayHContainStatusBar has already been true, the
// display height of action-bar-overlay-layout must include the height of the
// status bar always.
isOverlayLayoutDisplayHContainStatusBar =
overlayLayoutDisplayHeight == screenHeight;
}
if (!isOverlayLayoutDisplayHContainStatusBar) {
// In normal case, we need to plus the status bar height manually.
displayHeight = overlayLayoutDisplayHeight + statusBarHeight;
} else {
// In some case(such as Samsung S7 edge), the height of the
// action-bar-overlay-layout display bound already included the height of the
// status bar, in this case we doesn't need to plus the status bar height
// manually.
displayHeight = overlayLayoutDisplayHeight;
}
} else {
if (userRootView != null) {
userRootView.getWindowVisibleDisplayFrame(r);
displayHeight = (r.bottom - r.top);
} else {
Log.w("KeyBordUtil",
"user root view not ready so ignore global layout changed!");
displayHeight = notReadyDisplayHeight;
}
}
if (displayHeight == notReadyDisplayHeight) {
return;
}
calculateKeyboardHeight(displayHeight);
calculateKeyboardShowing(displayHeight);
previousDisplayHeight = displayHeight;
}
private static int getContentViewInvisibleHeight(final Activity activity) {
final View contentView = activity.findViewById(android.R.id.content);
final Rect outRect = new Rect();
contentView.getWindowVisibleDisplayFrame(outRect);
return contentView.getBottom() - outRect.bottom;
}