Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android NavigationView displays under NavigationBar, and cannot be clicked

As you can see, the background of NavigationView has been set android:clipToPadding='false', and it can be seen under transparent NavigationBar.

BackGround NavigationView

But the NavigationView(NavigationDrawer) cannot fully scroll up to above the NavigationBar, how to solve this?

I want the list items scroll to the top of NavigationBar, which means the last Send is not under but above NavigationBar.


layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        android:clipToPadding="false"
        android:clipChildren="false"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer">
    </android.support.design.widget.NavigationView>

</android.support.v4.widget.DrawerLayout>

Well, the code runs like this, and I cannot search for a useful answer.

Any idea is welcome, thanks!

like image 381
MewX Avatar asked Jan 14 '16 15:01

MewX


2 Answers

Thanks to mehrdad khosravi! His solution is really a good direction and is more artistic.

But I am too lazy, so I have another but not that artistic solution: extended from NavigationView.

package your.package;

import android.content.Context;
import android.support.design.widget.NavigationView;
import android.util.AttributeSet;

import another.package.ScreenTool;

/**
 * This view makes the NavigationDrawer fit system view.
 * Created by MewX on 1/19/2016.
 */
public class NavigationFitSystemView extends NavigationView {
    public NavigationFitSystemView(Context context) {
        super(context);
    }

    public NavigationFitSystemView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NavigationFitSystemView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthSpec, int heightSpec) {

        // TODO: optimize for tablet screen layout
        super.onMeasure(widthSpec, heightSpec- ScreenTool.getCurrentNavigationBarSize(getContext()).y);
    }
}

And, the ScreenTool.java:

package another.package;

import android.content.Context;
import android.graphics.Point;
import android.os.Build;
import android.view.Display;
import android.view.WindowManager;

/**
 * This class contains many screen-relate functions.
 * Created by MewX on 1/18/2016.
 */
@SuppressWarnings("unused")
public class ScreenTool {
    /**
     * get status bar height in px, this is the defined value whenever statusBar is displayed.
     * @param context current context
     * @return px int status bar height
     */
    public static int getStatusBarHeightValue(Context context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result; // in px
    }

    /**
     * get navigation bar height in px, this is the defined value whenever navBar is displayed.
     * @param context current context
     * @return px int navigation bar height
     */
    public static int getNavigationBarHeightValue(Context context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result; // in px
    }

    /**
     * get current navigation bar size:
     *   if bar not displaying, the values is zero;
     *   else is the width and height value;
     * @param context current context
     * @return new Point(width, height)
     */
    public static Point getCurrentNavigationBarSize(Context context) {
        Point appUsableSize = getAppUsableScreenSize(context);
        Point realScreenSize = getRealScreenSize(context);

        // navigation bar on the right
        if (appUsableSize.x < realScreenSize.x) {
            return new Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
        }

        // navigation bar at the bottom
        if (appUsableSize.y < realScreenSize.y) {
            return new Point(appUsableSize.x, realScreenSize.y - appUsableSize.y);
        }

        // navigation bar is not present
        return new Point();
    }

    /**
     * get application usable screen size.
     * @param context current size
     * @return new Point(width, height)
     */
    public static Point getAppUsableScreenSize(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }

    /**
     * get actual/real screen size, this is the full screen size.
     * @param context current context
     * @return new Point(width, height)
     */
    public static Point getRealScreenSize(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        Point size = new Point();

        if (Build.VERSION.SDK_INT >= 17) {
            display.getRealSize(size);
        } else if (Build.VERSION.SDK_INT >= 14) {
            try {
                size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
                size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
            } catch (Exception e) {
                size = new Point(0, 0);
            }
        }
        return size;
    }
}

Then, change the layout file from <android.support.design.widget.NavigationView /> to <your.package.NavigationFitSystemView />


At last, change your references in other sources, like MainActivity.java

Finally, the screen looks like this, and can be dynamically changed whereas the NavigationBar hides or shows.

NavigationFitSystemView

like image 57
MewX Avatar answered Sep 27 '22 18:09

MewX


remove

name="android:windowTranslucentNavigation">true

from your theme in style.xml

like image 39
Varun Chaudhary Avatar answered Sep 27 '22 18:09

Varun Chaudhary