5

I'm using Translucent Navigation bar by adding below attribute to make my app mobile nav menu looks like some Google apps where mobile nav bar is a bit transparent and content will visible through it.

<item name="android:windowTranslucentNavigation">true</item>

But my output is itenter image description here

I don't want my views to go under it. I just need it when there is More content to scroll on screen like when there is a scrolling activity or in recyclerview. But at the end I need my activity views to not overlap by it.

Any suggestions please...

Real Tech Hacks
  • 367
  • 3
  • 11

3 Answers3

2

You may need to apply insets to have space between bottom of the device and navigationbar. RootView is the top layout on xml file.

 rootView.setOnApplyWindowInsetsListener { view, insets ->

        recyclerview.run {
            setPadding(paddingLeft,paddingTop,paddingRight, insets.systemWindowInsetBottom)
        }

        insets
    }

With this snippet you will have transparent navigationbar but your RecyclerView will always be above navigationBar.

And add

android:clipToPadding="false"

flag, this works with RecyclerView, and other scrollable views i guess.

You can check out this medium article or Chris Bane's tivi app to get familiar with insets.

Also put an example on github

enter image description here

Thracian
  • 43,021
  • 16
  • 133
  • 222
  • Thanks for your response, but I'm not able to understand your answer. I'm using just one attribute in styles `true`. Can you please say what can I do next to achieve my goal in all activities. I had seen that medium article and tried it, but seems not working to me. I am not familiar in kotlin. – Real Tech Hacks Aug 30 '21 at 04:14
  • You need to call `setOnApplyWindowInsetsListener ` on your root view to get your devices insets, it includes height values for status bar as `systemWindowInsetTop` and navigationBar as `systemWindowInsetBottom`. Then you can use these values to add as padding to your scrollable view with ` `setPadding(paddingLeft,paddingTop,paddingRight, insets.systemWindowInsetBottom) `. And only to apply padding when you only scrolled to bottom use `android:clipToPadding="false"` on xml – Thracian Aug 30 '21 at 04:18
  • It is working in activities, but not working as expected in fragments and navigation UI. – Real Tech Hacks Aug 30 '21 at 06:07
  • For fragments you should check out whether your view is attached or not. In medium article it covers that scenario either. You should also add listener to see if your view attached and then do the same process. – Thracian Aug 30 '21 at 09:19
  • @RealTechHacks quoting from the medium article "This is a common scenario when you create views in Fragment.onCreateView(). The fix would be to make sure to simply call the method in onStart() instead, or use a listener to request insets once attached. The following extension function handles both cases:" – Thracian Aug 30 '21 at 09:19
  • The example i put on github works for fragments. But i made a check there to set padding when inset is not equal to zero – Thracian Aug 30 '21 at 09:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236560/discussion-between-thracian-and-real-tech-hacks). – Thracian Aug 30 '21 at 10:55
0

What you could try for a static view is:

android:layout_marginBottom="?android:attr/actionBarSize"

If in a ScrollView this obviously won´t work but you can still try to play around wiht different layers inside the xml and fit a margin or padding if needed.

Otherwise it might be helpful if you post your xml file to actually see what you try to implement.

Markus
  • 129
  • 1
  • 8
0

It is possible in both ScrollView and Recyclerview.

  • If there is scrollview in your Xml file then you should create two other layout(ex: LinearLayout1 as Scrollview child Layout and LinearLayout2 as LinearLayout1 child Layout) as a child layouts and set bottom margin in the Secode child layout(LinearLayout2) same as your bottom navigationBar height.

    Well, here is the example how you can get bottom navigationBar height.

                public int getNavigationBarHeight()
                 {
                     boolean hasMenuKey = ViewConfiguration.get(getApplicationContext()).hasPermanentMenuKey();
                     int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
                     if (resourceId > 0 && !hasMenuKey)
                     {
                         return getResources().getDimensionPixelSize(resourceId);
                     }
                     return 0;
                 }
    

Note: The height of the navigationBar is in px. So, you have to set margin of your child layout in px.

  • For Recyclerview, you can give bottom margin(RunTime) of parent layout in adapter class for the last item of the recyclerView same as navigationBar height.

Example:

               if (position==adapter_dueModelList.size()-1){// the list item
                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                            LinearLayout.LayoutParams.WRAP_CONTENT,
                            LinearLayout.LayoutParams.WRAP_CONTENT
                    );
                    params.setMargins(0, 0, 0, 132);//give margin same as a navigationBar height.
                    ((ViewHolder) holder).linear_layout.setLayoutParams(params);
                }
Vatsal Dholakiya
  • 545
  • 4
  • 19
  • Fixed number 132 is not always the correct navigationbar height for every device out there. If you check out [this link](https://chris.banes.dev/becoming-a-master-window-fitter-lon/) and video on yt you can see that it's not an advised behavior. – Thracian Aug 28 '21 at 15:42
  • @thracian please check I have said that you have to get navigationBar height and then you need to pass that size into bottom margin. Also, I have given that code in the post. – Vatsal Dholakiya Aug 28 '21 at 16:51