人生处万类,知识最为贤。这篇文章主要讲述检测Android导航栏方向相关的知识,希望能为你提供帮助。
有没有办法知道这个导航栏将在哪里显示为横向:
- 在Nexus7上它位于底部
- 在nexus 5上,它在右边。
答案通过将decor view的属性与当前的DisplayMetrics结合使用,您可以找到导航栏位于哪一侧。
// retrieve the position of the DecorView
Rect visibleFrame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleFrame);
DisplayMetrics dm = getResources().getDisplayMetrics();
// check if the DecorView takes the whole screen vertically or horizontally
boolean isRightOfContent = dm.heightPixels == visibleFrame.bottom;
boolean isBelowContent= dm.widthPixels== visibleFrame.right;
另一答案部分基于Pauland的答案(反过来基于
PhoneWindowManager
的实施),这是我目前正在使用的:public static boolean isSystemBarOnBottom(Context ctxt) {
Resources res=ctxt.getResources();
Configuration cfg=res.getConfiguration();
DisplayMetrics dm=res.getDisplayMetrics();
boolean canMove=(dm.widthPixels != dm.heightPixels &
&
cfg.smallestScreenWidthDp <
600);
return(!canMove || dm.widthPixels <
dm.heightPixels);
}
这适用于Nexus 7 2012和Nexus 4,每个都运行android 5.1。
在具有永久MENU键的设备上,没有系统栏。根据您的使用情况,您可能需要检查此案例:
ViewConfiguration.get(ctxt).hasPermanentMenuKey()
(其中
ctxt
是一些Context
)就个人而言,我正在使用它来尝试将滑动面板放在与系统条相反的轴上,因为系统条一侧的边框滑动有点难以触发。我不会使用这个,或任何其他算法(如依赖于
getDecorView()
的算法),任何关键的东西。另一答案我的解决方案
public static boolean hasNavBar (Resources resources)
{
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
if (id >
0)
return resources.getBoolean(id);
else
return false;
}public static int getNavigationBarHeight (Resources resources)
{
if (!Utils.hasNavBar(resources))
return 0;
int orientation = resources.getConfiguration().orientation;
//Only phone between 0-599 has navigationbar can move
boolean isSmartphone = resources.getConfiguration().smallestScreenWidthDp <
600;
if (isSmartphone &
&
Configuration.ORIENTATION_LANDSCAPE == orientation)
return 0;
int id = resources
.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android");
if (id >
0)
return resources.getDimensionPixelSize(id);
return 0;
}public static int getNavigationBarWidth (Resources resources)
{
if (!Utils.hasNavBar(resources))
return 0;
int orientation = resources.getConfiguration().orientation;
//Only phone between 0-599 has navigationbar can move
boolean isSmartphone = resources.getConfiguration().smallestScreenWidthDp <
600;
if (orientation == Configuration.ORIENTATION_LANDSCAPE &
&
isSmartphone)
{
int id = resources.getIdentifier("navigation_bar_width", "dimen", "android");
if (id >
0)
return resources.getDimensionPixelSize(id);
}return 0;
}
基于https://android.googlesource.com/platform/frameworks/base/+/9f65c4c34abb07bdda54649ed510af26f16e9c1b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java的解决方案
另一答案我的工作解决方案是:
public static boolean hasNavBar(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Point realPoint = new Point();
Display display = wm.getDefaultDisplay();
display.getRealSize(realPoint);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
return metrics.heightPixels + metrics.widthPixels != realPoint.y + realPoint.x;
}public static boolean isSystemBarOnBottom(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Point realPoint = new Point();
Display display = wm.getDefaultDisplay();
display.getRealSize(realPoint);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
Configuration cfg = context.getResources().getConfiguration();
boolean canMove = (metrics.widthPixels != metrics.heightPixels &
&
cfg.smallestScreenWidthDp <
600);
return (!canMove || metrics.widthPixels <
metrics.heightPixels);
}
另一答案这与我的应用程序一起使用,我使用半透明状态栏和导航栏来设置填充。
boolean navBarOnTheBottom(){
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int viewHeight = displaymetrics.heightPixels;
if (bkg.getHeight() == viewHeight)
{
Log.d(TAG, "nav bar on the side");
return false;
}
else{
Log.d(TAG, "nav bar on the bottom");
return true;
}
}
bkg它是保存我所有应用程序视图的主要linearLayout。确保bkg.getHeight()没有给你0,有些布局确实给了我0
编辑:如果上面的给你0,获得这样的布局高度
@Override
public void onWindowFocusChanged (boolean hasFocus) {
// the height will be set at this point
bkgHeight = bkg.getHeight();
}
另一答案请注意,从Android 7.1开始,导航栏也可能位于屏幕的左侧。为了确保您始终知道导航栏的位置,请使用
DisplayListener
检查Android 7.1及更高版本上的180°屏幕更改,如下所示:How to detect screen rotation through 180 degrees from landscape to landscape orientation?【检测Android导航栏方向】我已成功并可靠地使用此代码来确定导航栏位置的任何更改:
DisplayManager.DisplayListener displayListener;
@Override
protected void onCreate(Bundle savedInstanceState) {...displayListener = new DisplayManager.DisplayListener() {
private int lastRotation =
((WindowManager) getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getRotation();
@Override
public void onDisplayAdded(int displayId) {
}@Override
public void onDisplayChanged(int displayId) {
int rotation = ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getRotation();
if (rotation == Surface.ROTATION_90
&
&
lastRotation == Surface.ROTATION_270
|| rotation == Surface.ROTATION_270
&
&
lastRotation == Surface.ROTATION_90) {
onNavigationBarMoved(true);
}
lastRotation = rotation;
}@Override
public void onDisplayRemoved(int displayId) {
}
};
DisplayManager displayManager =
(DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
displayManager.registerDisplayListener(displayListener, null);
onNavigationBarMoved(false);
}@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onNavigationBarMoved(false);
}@Override
protected void onDestroy() {
if (displayListener != null) {
DisplayManager displayManager =
(DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
displayManager.unregisterDisplayListener(displayListener);
}
super.onDestroy();
}protected void onNavigationBarMoved(boolean lands
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 元素将无法在Constraintlayout Android Studio中正确居中
- 无法将PowerBI Desktop和PowerBI WebApp与Google Analytics连接
- 与.NET Web应用程序和.NET Mobile App共享数据库
- 如何在WinForms C#中使用LiveCharts库创建饼图
- 使用C#在图像上进行隐写术(隐藏信息)入门
- 如何在PHP中使用Imagick检查图像是否具有透明度
- 如何在Symfony 3的Twig视图的Dates上使用time_diff和ago(time ago)函数
- 如何在Twig中有条件地扩展模板或导入宏
- 如何防止XSS攻击并禁止PHP Markdown解析器生成的HTML中的特定标签