Search code examples
androidandroid-constraintlayoutandroid-scrollviewmaterial-components-android

Why does scrolling not work correctly when using WindowCompat.setDecorFitsSystemWindows(window, false)?


It looks like when I add

WindowCompat.setDecorFitsSystemWindows(window, false)

to my Android app, scrolling through the content on the screen while the keyboard is open is broken. It does not allow you to scroll to the last item on the screen. Here is the code I am using.

package com.example.myapplication

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import com.example.myapplication.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        WindowCompat.setDecorFitsSystemWindows(window, false)
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

    }

}
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/containerOfContainers"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:orientation="vertical">

        <TextView
            android:id="@+id/titleText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:gravity="center_horizontal"
            android:text="Title"
            android:textSize="40sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:layout_constraintTop_creator="1"
            tools:layout_editor_absoluteX="@dimen/spark_gap_tiny">

            <requestFocus />
        </TextView>

        <EditText
            android:id="@+id/first"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:paddingTop="150dp"
            android:text="1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/titleText" />


        <EditText
            android:id="@+id/second"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:paddingTop="150dp"
            android:text="2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/first" />

        <EditText
            android:id="@+id/third"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:paddingTop="150dp"
            android:text="3"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/second" />

        <EditText
            android:id="@+id/fourth"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:paddingTop="150dp"
            android:text="4"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/third" />

        <EditText
            android:id="@+id/fifth"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:paddingTop="150dp"
            android:text="5"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/fourth" />

        <EditText
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:paddingTop="150dp"
            android:text="6"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/fifth" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.myapplication">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.MyApplication">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Correct (I can scroll all the way down to 6 when the keyboard is open)

Correct

Wrong (I can only scroll to 4 when the keyboard is open)

Wrong

What could be causing this? It seems like a pretty simple use case.


Solution

  • Figured it out. I need to update the insets when they change. See code.

    package com.example.myapplication
    
    import android.os.Bundle
    import android.view.View
    import android.view.ViewGroup
    import android.view.WindowInsets
    import androidx.appcompat.app.AppCompatActivity
    import androidx.core.view.WindowCompat
    import androidx.core.view.updateLayoutParams
    import androidx.core.view.updateMargins
    import com.example.myapplication.databinding.ActivityMainBinding
    
    
    class MainActivity : AppCompatActivity() {
    
        private lateinit var binding: ActivityMainBinding
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            WindowCompat.setDecorFitsSystemWindows(window, false)
            binding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(binding.root)
    
    
            binding.root.setOnApplyWindowInsetsListener { _, _ ->
                applyKeyboardInsets(binding.root)
            }
    
        }
    
    
        private fun applyKeyboardInsets(root: View): WindowInsets {
    
            val insets = root.rootWindowInsets.getInsets(WindowInsets.Type.ime())
            root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                updateMargins(insets.left, insets.top, insets.right, insets.bottom)
            }
            return WindowInsets.Builder()
                .setInsets(WindowInsets.Type.ime(), insets)
                .build()
        }
    
    }