Simple One-line Solution
As suggested in many of above answers, for example
Simply getting navigation bar height may not be enough. We need to consider whether 1. navigation bar exists, 2. is it on the bottom, or right or left, 3. is app open in multi-window mode.
Fortunately you can easily bypass all the long coding by simply setting android:fitsSystemWindows="true"
in your root layout. Android system will automatically take care of adding necessary padding to the root layout to make sure that the child views don't get into the navigation bar or statusbar regions.
There is a simple one line solution
android:fitsSystemWindows="true"
or programatically
findViewById(R.id.your_root_view).setFitsSystemWindows(true);
you may also get root view by
findViewById(android.R.id.content).getRootView();
or
getWindow().getDecorView().findViewById(android.R.id.content)
For more details on getting root-view refer - https://stackoverflow.com/a/4488149/9640177