Search code examples
androidandroid-toolbarandroid-statusbarandroid-fullscreenandroid-window

Android - Full Screen without moving the content


I am developing a reading app from where users can read multiple types of documents.

This app also has a feature to enable full screen by touching any part of the screen. I am able to enable/disable full screen by hiding the status bar and the tool bar (ActionBar) with the following line of codes:

if (toolbar.getVisibility() == View.VISIBLE) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    appbar.animate().translationY(-112).setDuration(600L)
            .withEndAction(new Runnable() {
                @Override
                public void run() {
                    toolbar.setVisibility(View.GONE);
                }
            }).start();
} else {
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    toolbar.setVisibility(View.VISIBLE);
    appbar.animate().translationY(0).setDuration(600L).start();
}  

But the real issue is when I enable full screen the content moves upwards and when disable it moves downwards.

I don't want to move my content. I have seen in Google doc app that content does not move while enabling/disabling full screen.

Using RelativeLayout instead of CoordinatorLayout as a root layout I can avoid toolbar pushes the content but it pushes a little bit when I hide the status bar.

Please help.


Solution

  • Using RelativeLayout instead of CoordinatorLayout as a root layout I can avoid toolbar pushes the content but it pushes a little bit when I hide the status bar.

    Now your issue is that the status bar pushes the activity content down when it's shown.

    So, to solve this you can make the status bar overlapping with the activity window by adding the below to the activity's onCreate() method

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 
                             WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }
    

    UPDATE

    what to use if build SDK is lower than kitkat?

    To support APIs below Kitkat try to create a style.xml file for (v-19) qualifier, and add the below attributes

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

    UPDATE: using custom ActionBar

    Layout:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#000000">
    
            <ScrollView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scrollbars="vertical"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintTop_toTopOf="parent">
    
                <TextView
                    android:id="@+id/content"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:clickable="true"
                    android:focusable="true"
                    android:text="@string/long_text"
                    android:textColor="@android:color/white" />
    
            </ScrollView>
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true"
            android:background="#9E0557B5"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:layout_constraintTop_toTopOf="parent">
    
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    
        </com.google.android.material.appbar.AppBarLayout>
    
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    

    Behavior

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Toolbar toolbar = findViewById(R.id.toolbar);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                        WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
            }
            setSupportActionBar(toolbar);
    
            TextView content = findViewById(R.id.content);
            content.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (getSupportActionBar().isShowing()) {
                        getSupportActionBar().hide();
                        showSystemBar(false);
                    }
                    else {
                        getSupportActionBar().show();
                        showSystemBar(true);
                    }
                }
            });
        }
    
        private void showSystemBar(boolean isDisplayed) {
    
            int uiOptions;
            if (isDisplayed) {
                // show status bar
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
                    getWindow().getDecorView().setSystemUiVisibility(uiOptions);
                }
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            } else {
                // hide status bar
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
                    getWindow().getDecorView().setSystemUiVisibility(uiOptions);
                } else {
                    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
                }
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    
            }
    
        }
    
    }
    

    Use NoActionBar theme int style.xml

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    

    Override style.xml (v.19)

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>
    

    Preview