Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The view is overlaped by navigation bar in nexus 5. #68

Open
krishnalalstha opened this issue Aug 19, 2015 · 12 comments
Open

The view is overlaped by navigation bar in nexus 5. #68

krishnalalstha opened this issue Aug 19, 2015 · 12 comments

Comments

@krishnalalstha
Copy link

No description provided.

@yayaa
Copy link
Contributor

yayaa commented Sep 4, 2015

I had the same problem, and found this issue jfeinstein10/SlidingMenu#680
After a quick look at that issue and comments, i made below changes in ResideMenu.java and now it works.

@Override
protected boolean fitSystemWindows(Rect insets) {
    // Applies the content insets to the view's padding, consuming that
    // content (modifying the insets to be 0),
    // and returning true. This behavior is off by default and can be
    // enabled through setFitsSystemWindows(boolean)
    // in api14+ devices.
    int bottomPadding = viewActivity.getPaddingBottom() + insets.bottom;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        bottomPadding += getNavigationBarHeight();
    }
    this.setPadding(viewActivity.getPaddingLeft() + insets.left,
            viewActivity.getPaddingTop() + insets.top,
            viewActivity.getPaddingRight() + insets.right,
            bottomPadding);
    insets.left = insets.top = insets.right = insets.bottom = 0;
    return true;
}

private int getNavigationBarHeight() {
    Resources resources = getResources();
    int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
        return resources.getDimensionPixelSize(resourceId);
    }
    return 0;
}

@romanpozd
Copy link

I had similar issue with the navigationbar, I tried some solutions from the merged issue but it fixed the problem only in portrait mode, in landscape mode, when the navigationbar was at right of the screen i had white line and incorrect view. Also I tested my app with Google Nexus 9 tablet(NavigationBar always at the bottom, even in landscape mode) and previous solutions didn't help me.

All my activities inherits from the BaseActivity.class, and i set it like this.
Pay attention to first lines of code and the getRealScreenDimensions method that returns the real sizes of device screen.
visible.bottom returns visible screen size (without the navigationbar), compares it with the real device height and set true or false.
Also pay attention to attachToActivity method that I customized.

BaseActivity.class

protected void menuConfiguration() {

    Rect visible = new Rect();
    getWindow().getDecorView().getWindowVisibleDisplayFrame(visible);
    // Method that gets device real size
    getRealScreenDimensions();

    // Check if navigationbar at right or bottom
    boolean navAtRight = screenHeight == visible.bottom;
    boolean navAtBottom = screenWidth == visible.right;

    int navigationSize;
    if (navAtRight)
        navigationSize = screenWidth - visible.right;
    else
        navigationSize = screenHeight - visible.bottom;

    resideMenu = new ResideMenu(this);
    resideMenu.setBackground(R.drawable.background);
    resideMenu.attachToActivity(this,navAtRight,navAtBottom,navigationSize);
    resideMenu.setScaleValue(0.6f);

}

 private void getRealScreenDimensions(){
    final int version = android.os.Build.VERSION.SDK_INT;
    Display display = getWindowManager().getDefaultDisplay();

    if (version >= 15)
    {
        Point size = new Point();
        display.getRealSize(size);
        screenWidth = size.x;
        screenHeight = size.y;
    }
    else
    {
        screenWidth = display.getWidth();
        screenHeight = display.getHeight();
    }
}

Also check customized attachToActivity and fitSystemWindows methods in ResideMenu.java

ResideMenu.java

    public void attachToActivity(Activity activity,boolean navAtRight, boolean navAtBottom, int navigationSize) {
    initValue(activity);
    this.navigationSize = navigationSize;
    this.navAtRight = navAtRight;
    this.navAtBottom = navAtBottom;
    setShadowAdjustScaleXByOrientation();
    viewDecor.addView(this, 0);
}

    @Override
protected boolean fitSystemWindows(Rect insets) {
    // Applies the content insets to the view's padding, consuming that content (modifying the insets to be 0),
    // and returning true. This behavior is off by default and can be enabled through setFitsSystemWindows(boolean)
    // in api14+ devices.



    int bottomPadding = viewActivity.getPaddingBottom() + insets.bottom;
    int rightPadding = viewActivity.getPaddingRight() + insets.right;
    int topPadding = 0;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (navAtBottom){
            bottomPadding += navigationSize;
        }
        else if (navAtRight)
            rightPadding += navigationSize;
    }

    this.setPadding(viewActivity.getPaddingLeft() + insets.left,
            topPadding,
            rightPadding,
            bottomPadding);
    insets.left = insets.top = insets.right = insets.bottom = 0;
    return true;
}

Hope it will help someone.

@yayaa
Copy link
Contributor

yayaa commented Oct 8, 2015

Wow, yeah you're right... Just because my application was only portrait mode i didn't check for the rest, my bad. But isn't that possible to fix it only by editting fitSystemWindows?

@romanpozd
Copy link

Hmm... This is the first solution I found.. I'll check if there a way to edit only in ResideMenu.java and update if there is something new.

@RlagoMan
Copy link
Contributor

RlagoMan commented Nov 3, 2015

Hello,
In Lollipop devices, fitSystemWindows(Rect insets) is deprecated. I'm using a similar approach as @romanpozd:

    @TargetApi(21)
    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        Rect insetsRect = new Rect(
                insets.getSystemWindowInsetLeft(),
                insets.getSystemWindowInsetTop(),
                insets.getSystemWindowInsetRight(),
                insets.getSystemWindowInsetBottom());
        setInsets(insetsRect);
        return insets.replaceSystemWindowInsets(insetsRect);
    }

    @SuppressWarnings("deprecation")
    @Override
    protected boolean fitSystemWindows(Rect insets) {
        if (Build.VERSION.SDK_INT < 21) {
            setInsets(insets);
            return true;
        }
        return super.fitSystemWindows(insets);        
    }

The method setInsets(Rect insets) is similar to fitSystemWindows(Rect insets) (by romanpozd), but now it is called from a different method in each case.

Hope this helps!

@yamila-fraiman
Copy link

Could you update the repo?

@dasheck0
Copy link

None of the solutions above works for the Nexus 7 (and probably others). The reason is that the height of the navigation bar is dependent on the device type (smartphone and tablet) as well as on the orientation (landscape and portrait). The following code respects this issues and therefore works also on the Nexus 7.

@Override protected boolean fitSystemWindows(Rect insets) {
    int bottomPadding = insets.bottom;
    bottomPadding += getNavBarHeight(getContext());

    this.setPadding(viewActivity.getPaddingLeft() + insets.left, viewActivity.getPaddingTop() + insets.top,
        viewActivity.getPaddingRight() + insets.right, viewActivity.getPaddingBottom() + bottomPadding);
    insets.left = insets.top = insets.right = insets.bottom = 0;
    return true;
  }

  private int getNavBarHeight(Context context) {
    int result = 0;
    boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
    boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);

    if(!hasMenuKey && !hasBackKey) {
      Resources resources = getContext().getResources();

      int orientation = getResources().getConfiguration().orientation;
      int resourceId;
      if (isTablet(context)){
        resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android");
      }  else {
        resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_width", "dimen", "android");
      }

      if (resourceId > 0) {
        return getResources().getDimensionPixelSize(resourceId);
      }
    }
    return result;
  }

  private boolean isTablet(Context context) {
    return (context.getResources().getConfiguration().screenLayout
        & Configuration.SCREENLAYOUT_SIZE_MASK)
        >= Configuration.SCREENLAYOUT_SIZE_LARGE;
  }

@MarcoGuerrieri
Copy link

The only way that I've found to know if a device has the software nav bar (other methods with phones like OnePlus will not return the correct value)

public static boolean hasSoftwareNavBar(Context ctx) {

    if (!mCached) {
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            mHasSoftwareNavBar = false;
            mCached = true;
            return false;
        }
        Display d = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        d.getRealMetrics(realDisplayMetrics);

        int realHeight = realDisplayMetrics.heightPixels;
        int realWidth = realDisplayMetrics.widthPixels;

        DisplayMetrics displayMetrics = new DisplayMetrics();
        d.getMetrics(displayMetrics);

        int displayHeight = displayMetrics.heightPixels;
        int displayWidth = displayMetrics.widthPixels;

        mHasSoftwareNavBar = (realWidth > displayWidth) || (realHeight > displayHeight);
        mCached = true;
    }

    return mHasSoftwareNavBar;
}

@Kishanjvaghela
Copy link

I created demo project with AppCompat for this library and also solve this issue.
https://github.com/Kishanjvaghela/SlidingMenu-AppCompat

@wondersoftwares671
Copy link

wondersoftwares671 commented Sep 2, 2017

The Simple solution that is working for me for now is,
Get Navigation bar height and set padding to root layout of activity in OnCreate() after setContentView.

.....
     int navHeight = getNavHeight();
     if (navHeight > 0) {
         (findViewById(R.id.rlMain)).setPadding(0, 0, 0, navHeight);
     }
.....
 private int getNavHeight() {
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
         return 0;
     try {

         Resources resources = getResources();
         int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
         if (resourceId > 0) {
             boolean hasMenuKey = ViewConfiguration.get(getApplicationContext()).hasPermanentMenuKey();
             boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);

             if (!hasMenuKey && !hasBackKey) {
                 return resources.getDimensionPixelSize(resourceId);
             }
         }
     } catch (Exception ex) {
         return 0;
     }
     return 0;
 }

@ghost
Copy link

ghost commented Jul 9, 2018

i have same issue can any one solve this problem ?

@dasheck0
Copy link

dasheck0 commented Jul 9, 2018

@MohammadAliK Did you try any of the solutions mentioned above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants