Skip to content

Commit e06a119

Browse files
pubiqqhunterstich
authored andcommitted
[Internal] Add compat method to get the screen size
Resolves #3221 GIT_ORIGIN_REV_ID=9323e23689386561d38b0c8c73114e0db7a30557 PiperOrigin-RevId: 509548792
1 parent b3f32d4 commit e06a119

File tree

3 files changed

+128
-17
lines changed

3 files changed

+128
-17
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright (C) 2023 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.android.material.internal;
18+
19+
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20+
21+
import android.content.Context;
22+
import android.graphics.Point;
23+
import android.graphics.Rect;
24+
import android.os.Build;
25+
import android.util.Log;
26+
import android.view.Display;
27+
import android.view.WindowManager;
28+
import androidx.annotation.NonNull;
29+
import androidx.annotation.RequiresApi;
30+
import androidx.annotation.RestrictTo;
31+
import java.lang.reflect.InvocationTargetException;
32+
import java.lang.reflect.Method;
33+
34+
/**
35+
* A util class for window operations.
36+
*
37+
* @hide
38+
*/
39+
@RestrictTo(LIBRARY_GROUP)
40+
public class WindowUtils {
41+
42+
private static final String TAG = WindowUtils.class.getSimpleName();
43+
44+
private WindowUtils() {}
45+
46+
@NonNull
47+
public static Rect getCurrentWindowBounds(@NonNull Context context) {
48+
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
49+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
50+
return Api30Impl.getCurrentWindowBounds(windowManager);
51+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
52+
return Api17Impl.getCurrentWindowBounds(windowManager);
53+
} else {
54+
return Api14Impl.getCurrentWindowBounds(windowManager);
55+
}
56+
}
57+
58+
@RequiresApi(api = Build.VERSION_CODES.R)
59+
private static class Api30Impl {
60+
61+
@NonNull
62+
static Rect getCurrentWindowBounds(@NonNull WindowManager windowManager) {
63+
return windowManager.getCurrentWindowMetrics().getBounds();
64+
}
65+
}
66+
67+
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
68+
private static class Api17Impl {
69+
70+
@NonNull
71+
static Rect getCurrentWindowBounds(@NonNull WindowManager windowManager) {
72+
Display defaultDisplay = windowManager.getDefaultDisplay();
73+
74+
Point defaultDisplaySize = new Point();
75+
defaultDisplay.getRealSize(defaultDisplaySize);
76+
77+
Rect bounds = new Rect();
78+
bounds.right = defaultDisplaySize.x;
79+
bounds.bottom = defaultDisplaySize.y;
80+
81+
return bounds;
82+
}
83+
}
84+
85+
private static class Api14Impl {
86+
87+
@NonNull
88+
static Rect getCurrentWindowBounds(@NonNull WindowManager windowManager) {
89+
Display defaultDisplay = windowManager.getDefaultDisplay();
90+
Point defaultDisplaySize = getRealSizeForDisplay(defaultDisplay);
91+
92+
Rect bounds = new Rect();
93+
if (defaultDisplaySize.x == 0 || defaultDisplaySize.y == 0) {
94+
defaultDisplay.getRectSize(bounds);
95+
} else {
96+
bounds.right = defaultDisplaySize.x;
97+
bounds.bottom = defaultDisplaySize.y;
98+
}
99+
100+
return bounds;
101+
}
102+
103+
private static Point getRealSizeForDisplay(Display display) {
104+
Point size = new Point();
105+
try {
106+
Method getRealSizeMethod = Display.class.getDeclaredMethod("getRealSize", Point.class);
107+
getRealSizeMethod.setAccessible(true);
108+
getRealSizeMethod.invoke(display, size);
109+
} catch (NoSuchMethodException e) {
110+
Log.w(TAG, e);
111+
} catch (IllegalAccessException e) {
112+
Log.w(TAG, e);
113+
} catch (InvocationTargetException e) {
114+
Log.w(TAG, e);
115+
}
116+
return size;
117+
}
118+
}
119+
}

lib/java/com/google/android/material/navigation/NavigationView.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import android.graphics.Canvas;
2828
import android.graphics.Color;
2929
import android.graphics.Path;
30+
import android.graphics.Rect;
3031
import android.graphics.RectF;
3132
import android.graphics.drawable.ColorDrawable;
3233
import android.graphics.drawable.Drawable;
@@ -44,7 +45,6 @@
4445
import androidx.appcompat.view.menu.MenuItemImpl;
4546
import androidx.appcompat.widget.TintTypedArray;
4647
import android.util.AttributeSet;
47-
import android.util.DisplayMetrics;
4848
import android.util.TypedValue;
4949
import android.view.Gravity;
5050
import android.view.Menu;
@@ -73,6 +73,7 @@
7373
import com.google.android.material.internal.NavigationMenuPresenter;
7474
import com.google.android.material.internal.ScrimInsetsFrameLayout;
7575
import com.google.android.material.internal.ThemeEnforcement;
76+
import com.google.android.material.internal.WindowUtils;
7677
import com.google.android.material.resources.MaterialResources;
7778
import com.google.android.material.ripple.RippleUtils;
7879
import com.google.android.material.shape.MaterialShapeDrawable;
@@ -975,11 +976,10 @@ public void onGlobalLayout() {
975976

976977
Activity activity = ContextUtils.getActivity(getContext());
977978
if (activity != null && VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
978-
DisplayMetrics displayMetrics = new DisplayMetrics();
979-
activity.getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
979+
Rect displayBounds = WindowUtils.getCurrentWindowBounds(activity);
980980

981981
boolean isBehindSystemNav =
982-
displayMetrics.heightPixels - getHeight() == tmpLocation[1];
982+
displayBounds.height() - getHeight() == tmpLocation[1];
983983
boolean hasNonZeroAlpha =
984984
Color.alpha(activity.getWindow().getNavigationBarColor()) != 0;
985985
setDrawBottomInsetForeground(
@@ -988,8 +988,8 @@ public void onGlobalLayout() {
988988
// The navigation view could be right aligned or just hidden out of view in a drawer
989989
// layout when the global layout listener is called.
990990
boolean isOnRightSide =
991-
(displayMetrics.widthPixels == tmpLocation[0])
992-
|| (displayMetrics.widthPixels - getWidth() == tmpLocation[0]);
991+
(displayBounds.width() == tmpLocation[0])
992+
|| (displayBounds.width() - getWidth() == tmpLocation[0]);
993993

994994
setDrawRightInsetForeground(isOnRightSide);
995995
}

lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import android.os.Looper;
4949
import android.os.Message;
5050
import android.util.AttributeSet;
51-
import android.util.DisplayMetrics;
5251
import android.util.Log;
5352
import android.view.Gravity;
5453
import android.view.LayoutInflater;
@@ -60,7 +59,6 @@
6059
import android.view.ViewParent;
6160
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
6261
import android.view.WindowInsets;
63-
import android.view.WindowManager;
6462
import android.view.accessibility.AccessibilityManager;
6563
import android.widget.FrameLayout;
6664
import androidx.annotation.ColorInt;
@@ -83,6 +81,7 @@
8381
import com.google.android.material.color.MaterialColors;
8482
import com.google.android.material.internal.ThemeEnforcement;
8583
import com.google.android.material.internal.ViewUtils;
84+
import com.google.android.material.internal.WindowUtils;
8685
import com.google.android.material.motion.MotionUtils;
8786
import com.google.android.material.resources.MaterialResources;
8887
import com.google.android.material.shape.MaterialShapeDrawable;
@@ -297,8 +296,9 @@ public void run() {
297296
}
298297
// Calculate current bottom inset, factoring in translationY to account for where the
299298
// view will likely be animating to.
299+
int screenHeight = WindowUtils.getCurrentWindowBounds(context).height();
300300
int currentInsetBottom =
301-
getScreenHeight() - getViewAbsoluteBottom() + (int) view.getTranslationY();
301+
screenHeight - getViewAbsoluteBottom() + (int) view.getTranslationY();
302302
if (currentInsetBottom >= extraBottomMarginGestureInset) {
303303
// No need to add extra offset if view is already outside of bottom gesture area
304304
return;
@@ -823,14 +823,6 @@ private int getViewAbsoluteBottom() {
823823
return absoluteLocation[1] + view.getHeight();
824824
}
825825

826-
@RequiresApi(VERSION_CODES.JELLY_BEAN_MR1)
827-
private int getScreenHeight() {
828-
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
829-
DisplayMetrics displayMetrics = new DisplayMetrics();
830-
windowManager.getDefaultDisplay().getRealMetrics(displayMetrics);
831-
return displayMetrics.heightPixels;
832-
}
833-
834826
private void setUpBehavior(CoordinatorLayout.LayoutParams lp) {
835827
// If our LayoutParams are from a CoordinatorLayout, we'll setup our Behavior
836828
CoordinatorLayout.LayoutParams clp = lp;

0 commit comments

Comments
 (0)