Android full screen navigation bar transparency bleeds onto navigation view - android

I'm using design library navigation view in full screen. But transparency of Navigation Bar and Status Bar bleeds onto NavigationView.Transparent black rectangles occur on right and top of the NavigationView.
My Layout
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/layout_custom_view" />
</RelativeLayout>
<!-- Navigation View -->
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_view_header"
app:menu="#menu/navigation_menu" />
MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (Build.VERSION.SDK_INT < 16) {
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
hideSystemUI();
}
setContentView(R.layout.activity_main);
// Set NavigationView with Header and Menu
setNavigationView();
}
/*
* ************ SETTING FULLSCREEN TRANSIONS ************
*/
/**
* Hide Status and Navigation bars
*/
public void hideSystemUI() {
if (Build.VERSION.SDK_INT >= 16) {
View decorView = getWindow().getDecorView();
// Hide both the navigation bar and the status bar.
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and
// higher, but as
// a general rule, you should design your app to hide the status bar
// whenever you
// hide the navigation bar.
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// Views can use nav bar space if set
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// hide nav bar
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// hide status bar
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUI();
}
}

Removing View.SYSTEM_UI_FLAG_LAYOUT_STABLE solves the issue.

Related

Full Screen Immersive Mode without layout bounce

How can one toggle between immersive to non-immersive mode without layout being re-calculated and thus experience a bounce effect?
Here's the relevant code that I'm using to toggle between the states:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
immersive_btn.setOnClickListener {
toggleImmersive()
}
}
val isInFullScreenImmersiveMode: Boolean
get() = window!!.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_IMMERSIVE == View.SYSTEM_UI_FLAG_IMMERSIVE
private fun toggleImmersive() {
if (isInFullScreenImmersiveMode) {
showSystemBar()
} else {
setFullScreenImmersiveMode()
}
}
fun showSystemBar() {
window!!.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
}
fun setFullScreenImmersiveMode() {
window!!.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE)
}
A video showing the bounce:
Only solution I came up with is using window?.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN) in OnCreate() but that would result in another problem: The status bar won't be shown, even when not in full screen immersive mode.
Edit: layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/immersive_btn"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Toggle Immersive" />
</RelativeLayout>

Remove gap from navigation drawer layout

I have created an application that has a navigation view.
when the application in fullscreen then I open that navigation-view that shows me the black overlay on top of navigation-view and also shows me the gap between the bottom of the screen and the bottom of navigation-view. For that.
xml code
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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"
tools:openDrawer="start">
...
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
tools:ignore="RtlSymmetry">
<!--PlayList Layout-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcvVideoPlaylist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:fitsSystemWindows="false"
tools:listitem="#layout/item_video_playlist" />
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
for fullscreen code
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
anyone give me the solution to remove that overlay from navigation-view and gap in that navigation-view
you can use this code:
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/rv">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
You can use this class for fullscreen Activity where status and navigation view does not bleed into NavigationView.
I had the same problem and tried the combination of system flags and found the right combination.
// Removes bleeding transparency onto navigation-view
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
Here is my fullscreen Activity.
public class FullScreenAppCompatActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT < 14) {
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
hideSystemUI();
}
}
/*
* ************ SETTING FULLSCREEN TRANSITIONS ************
*/
/**
* Hide Status and Navigation bars
*/
#SuppressLint("InlinedApi")
public void hideSystemUI() {
View decorView = getWindow().getDecorView();
// Hide both the navigation bar and the status bar.
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and
// higher, but as
// a general rule, you should design your app to hide the status bar
// whenever you
// hide the navigation bar.
// Navigation bar hiding: Backwards compatible to ICS.
// SELECTIVE FLAGS final code: 5890
// setSelectedFlags(decorView);
// NO SELECTION OF SDK_INT flag final cod: 5894
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// Views can use nav bar space if set
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Navigation bar hiding: Backwards compatible to ICS.
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// Status bar hiding: Backwards compatible to Jellybean
| View.SYSTEM_UI_FLAG_FULLSCREEN
// Immersive mode: Backward compatible to KitKat.
// Note that this flag doesn't do anything by itself, it only
// augments the behavior
// of HIDE_NAVIGATION and FLAG_FULLSCREEN. For the purposes of
// this sample
// all three flags are being toggled together.
// Note that there are two immersive mode UI flags, one of which
// is referred to as "sticky".
// Sticky immersive mode differs in that it makes the navigation
// and status bars
// semi-transparent, and the UI flag does not get cleared when
// the user interacts with
// the screen.
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
// Removes bleeding transparency onto navigation-view
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
private void setSelectedFlags(View decorView) {
int selectedFlags = 0;
if (Build.VERSION.SDK_INT >= 14) {
selectedFlags ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
Toast.makeText(getApplicationContext(), "View.SYSTEM_UI_FLAG_HIDE_NAVIGATION flag " + selectedFlags,
Toast.LENGTH_SHORT).show();
}
// Status bar hiding: Backwards compatible to Jellybean
if (Build.VERSION.SDK_INT >= 16) {
selectedFlags ^= (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// Views can use nav bar space if set
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Toast.makeText(getApplicationContext(), "View.SYSTEM_UI_FLAG_FULLSCREEN flag " + selectedFlags,
Toast.LENGTH_SHORT).show();
}
if (Build.VERSION.SDK_INT >= 19) {
selectedFlags ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
Toast.makeText(getApplicationContext(), "Final SELECTED flag " + selectedFlags, Toast.LENGTH_SHORT).show();
decorView.setSystemUiVisibility(selectedFlags);
int currentVisibility = getWindow().getDecorView().getSystemUiVisibility();
Toast.makeText(getApplicationContext(), "Initial visibility flag " + currentVisibility, Toast.LENGTH_SHORT)
.show();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUI();
}
}
}

CollapsingToolBarLayout and statusbar transparency

I'm trying make my status bar overlay over my content, which includes a CollapsingToolBarLayout ( inside CoordinatorLayout obviously ). So this is my current afford to make it happen;
a sampling from my layout is in the following:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="240dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="false"
app:contentScrim="?attr/colorPrimary">
<ImageView
android:id="#+id/employeeAvatarImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
And in the source, I did the following;
private void setupDecorView() {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
private void setupStatusBar() {
Window window = getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.parseColor("#3F51B5FF"));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
} else {
}
}
And I keep getting this image in the initial looking. Status bar is having is original color - no transparency.
However, when I first attemp to scroll, the status bar gets the transparent color I've set and want like the following:
So what might be the problem? Any ideas?

Scrolling animation in NavigationView

My activity has a NavigationView inside a DrawerLayout.
When user clicks on a button in the NavigationView header, I would like to scroll to top the DrawerLayout/NavigationView with an animation.
It seems that NavigationView and DrawerLayout don't provide a method to get the actual scroll position (getScrollY() and getScrollX() always return 0) and so I can't do that.
How can I scroll to top with an animation?
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- My content -->
<android.support.design.widget.NavigationView
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_view_header"
app:menu="#menu/my_navigation_items" />
</android.support.v4.widget.DrawerLayout>
you need to scroll the NavigationMenuView.
In the below code, it will scroll to top when click on any item in menu
NavigationView navigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public boolean onNavigationItemSelected(MenuItem item) {
//here will scroll to top
((NavigationMenuView)navigationView.getChildAt(0)).smoothScrollToPosition(0);
return true;
}
EDIT: If you want to protect against possible changes down the road, you can use reflection here, like so:
// try to scroll to the top of the navigation menu, if possible
if (navigationView.getChildCount() > 0) {
View childView = navigationView.getChildAt(0);
try {
Method scroll = childView.getClass().getMethod("smoothScrollToPosition", int.class);
scroll.invoke(childView, 0);
} catch (NoSuchMethodException |
SecurityException |
IllegalAccessException |
InvocationTargetException e) {
Log.d(TAG, "smoothScrollToPosition", e);
}
}
You can simple user smoothScrollToPosition(0) as NavigationMenuView is extend from RecyclerView
see the source code for NavigationMenuView
e.g
navigationView.smoothScrollToPosition(0);

How to show a custom actionbar view from one fragment only

I have a requirement for my app that a custom action bar view be shown from one fragment only (the landing page fragment). The problem is that this action bar is appearing when the user navigates to other fragments. Is there a way to do this without disabling custom view on every fragment?
Thanks
For this issue, only show actionbar for one fragment without show on all other fragments, solution could be very easy:
In your activity that hosts your fragments:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
... ...
// for API >= 11
getActionBar.hide();
// for API < 11
getSupportActionBar().hide();
... ...
}
Then in the fragment that you want to show actionbar:
#Override
public void onAttach(Activity activity){
activity.getActionBar().show(); //getSupportActionBar() for API<11
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) {
getActivity().getActionBar().hide(); //getSupportActionBar() for API<11
} else {
getActivity().getActionBar().show(); //getSupportActionBar() for API<11
}
}
Well, I'm just trying to suggest. Why not removing the action bar to all the fragments and just creating a single fragment (the landing page) with a custom action bar thru layout?
To remove ActionBar to all fragments, add this code to tag:
android:theme="#android:style/Theme.Light.NoTitleBar"
Create a Layout with action bar for your landing page through xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/rlMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<RelativeLayout
android:id="#+id/rlHeaderMain"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:background="#000000"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="5dp" >
</RelativeLayout>

Categories

Resources