Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检测Android导航栏方向_Android - Fatal编程技术网

检测Android导航栏方向

检测Android导航栏方向,android,Android,是否有办法知道此导航栏将在何处显示: 在Nexus7上,它位于底部 在Nexus5上,它位于右侧 谢谢 通过将的属性与电流结合使用,您可以找到导航栏位于哪一侧。 这是我的应用程序,我使用半透明的状态栏和导航栏来设置填充 boolean navBarOnTheBottom(){ DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay()

是否有办法知道此导航栏将在何处显示:

  • 在Nexus7上,它位于底部
  • 在Nexus5上,它位于右侧
谢谢


通过将的属性与电流结合使用,您可以找到导航栏位于哪一侧。


这是我的应用程序,我使用半透明的状态栏和导航栏来设置填充

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它是保存我所有应用程序视图的主要线性布局。 确保bkg.getHeight()没有给你0,在一些布局中它确实给了我0

编辑: 如果上面的一个给你0,那么得到这样的布局高度

@Override
    public void onWindowFocusChanged (boolean hasFocus) {
        // the height will be set at this point
        bkgHeight = bkg.getHeight();
    }
我的解决方案

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;
}
公共静态布尔hasNavBar(参考资料)
{
intid=resources.getIdentifier(“config_showNavigationBar”、“bool”、“android”);
如果(id>0)
返回resources.getBoolean(id);
其他的
返回false;
}
公共静态int getNavigationBarHeight(参考资料)
{
if(!Utils.hasNavBar(参考资料))
返回0;
int-orientation=resources.getConfiguration().orientation;
//只有0-599之间的电话具有navigationbar才能移动
布尔值isSmartphone=resources.getConfiguration().smallestScreenWidthDp<600;
if(isSmartphone&&Configuration.ORIENTATION\u横向==ORIENTATION)
返回0;
int id=资源
.getIdentifier(方向==配置.orientation\u纵向?“导航栏高度”:“导航栏高度\u横向”、“dimen”、“android”);
如果(id>0)
返回资源.getDimensionPixelSize(id);
返回0;
}
公共静态int getNavigationBarWidth(参考资料)
{
if(!Utils.hasNavBar(参考资料))
返回0;
int-orientation=resources.getConfiguration().orientation;
//只有0-599之间的电话具有navigationbar才能移动
布尔值isSmartphone=resources.getConfiguration().smallestScreenWidthDp<600;
如果(方向==Configuration.orientation\u横向和isSmartphone)
{
intid=resources.getIdentifier(“导航条宽度”、“尺寸”、“安卓”);
如果(id>0)
返回资源.getDimensionPixelSize(id);
}
返回0;
}
基于
部分基于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);
  }
(其中
ctxt
是一些
Context


就我个人而言,我用它来尝试让滑动面板位于系统栏的相反轴上,因为系统栏侧面的挡板滑动有点难以触发。我不会使用此算法或任何其他算法(如依赖于
getDecorView()
)的算法)来处理任何关键问题。

我的工作解决方案是:

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);
    }
public静态布尔hasNavBar(上下文){
WindowManager wm=(WindowManager)context.getSystemService(context.WINDOW\u服务);
点realPoint=新点();
Display Display=wm.getDefaultDisplay();
display.getRealSize(realPoint);
DisplayMetrics=新的DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
返回metrics.heightPixels+metrics.widthPixels!=realPoint.y+realPoint.x;
}
公共静态布尔值IsSystemOnBottom(上下文){
WindowManager wm=(WindowManager)context.getSystemService(context.WINDOW\u服务);
点realPoint=新点();
Display Display=wm.getDefaultDisplay();
display.getRealSize(realPoint);
DisplayMetrics=新的DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
Configuration cfg=context.getResources().getConfiguration();
布尔canMove=(metrics.widthPixels!=metrics.heightPixels&&
cfg.smallest屏幕宽度dp<600);
返回(!canMove | | metrics.widthPixels
请注意,从Android 7.1开始,导航栏也可能位于屏幕左侧。为了确保您始终知道导航栏的位置,请使用
DisplayListener
检查Android 7.1及更高版本上的180°屏幕更改,如下所示:

我已成功可靠地使用此代码确定导航栏位置的任何更改:

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 landscapeScreenRotation) {
    boolean leftSideNavigationBar = Build.VERSION.SDK_INT > Build.VERSION_CODES.N
                         && ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
                                .getDefaultDisplay().getRotation() == Surface.ROTATION_270;
    // add whatever else you need here
}

请记住,将已在横向中的设备旋转180°时,不会重新创建活动,因此,在导航栏移动的内部,
landscapeScreenRotation
的值将告诉您何时发生这种情况,以便您可以相应地重新调整UI。

为什么您需要知道这一点?Nexus 7和Nexus 5都没有永久的菜单键。因此,我可以避免将交互式UI放置在后退按钮附近。另外,我想知道横向和纵向的宽度/高度,这比任何方向改变都要早。@ianhanniballake。。。糟糕的是,我要的是导航栏,不是菜单键。我编辑了文章。如果显示软键盘,这可能无法正常工作。键盘高度从显示框中减去。在Nexus 5上,isRightOfContent和isBelowContent都是trueHi Commonware。这个解决方案也适用于导航栏吗?另外,您能否提供一些关于为什么需要canMove的背景信息?@sudocoder:“这个解决方案也适用于导航栏吗?”——我不确定您认为“导航栏”是什么。自蜂巢公司IIRC以来,该术语从未被使用过。“为什么需要canMove?”--因为在某些设备和操作系统版本上,系统栏会改变位置。所谓“导航栏”,我指的是OP提供的图片中红色箭头所指的内容。我将花一些时间来取消“(!canMove | dm.widthPixelspublic 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); }
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 landscapeScreenRotation) {
    boolean leftSideNavigationBar = Build.VERSION.SDK_INT > Build.VERSION_CODES.N
                         && ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
                                .getDefaultDisplay().getRotation() == Surface.ROTATION_270;
    // add whatever else you need here
}