Android opening edittext above the keyboard

37 Views Asked by At

Imagine that I have 10 inputs on the screen and they are in the scrollview, and I have a sticky button at the bottom. When I focus on an input, I want the input to remain on the keyboard and I want it to be scrollable.

I wrote a class for scrollview;

class AdjustingScrollView(context: Context, attrs: AttributeSet) : NestedScrollView(context, attrs) {
        var keyboardOpen = false
            set(value) {
                field = value
                requestLayout()
            }
    
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            var modifiedHeightMeasureSpec = heightMeasureSpec
            if (keyboardOpen) {
                val rootView = rootView ?: return
                val keyboardHeight = calculateKeyboardHeight(rootView)
                modifiedHeightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) - keyboardHeight, MeasureSpec.EXACTLY)
            }
            super.onMeasure(widthMeasureSpec, modifiedHeightMeasureSpec)
        }
    
        fun calculateKeyboardHeight(rootView: View): Int {
            val rect = Rect()
            rootView.getWindowVisibleDisplayFrame(rect)
            val displayHeight = rootView.height
            val visibleAreaHeight = rect.height()
            return (displayHeight - visibleAreaHeight).takeIf { it > displayHeight * 0.15 } ?: 0
        }
    }

xml;

 <AdjustingScrollView
        android:id="@+id/scrollViewRoot"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.appcompat.widget.LinearLayoutCompat
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

in fragment;

val rootView = view?.rootView
scrollViewRoot.viewTreeObserver.addOnGlobalLayoutListener {
                val r = Rect()
                rootView?.getWindowVisibleDisplayFrame(r)
                val screenHeight = rootView?.height ?: 0
                val keypadHeight = screenHeight - r.bottom

                scrollViewRoot.keyboardOpen = keypadHeight > screenHeight * 0.15
            }

input.setOnFocusChangeListener { v, hasFocus ->
                if (hasFocus) {
                    scrollViewRoot.postDelayed({
                        val additionalPadding = dpToPx(16)
                        val location = IntArray(2)
                        v.getLocationInWindow(location)
                        val viewBottom = location[1] + v.height

                        val r = Rect()
                        rootView?.getWindowVisibleDisplayFrame(r)
                        val screenHeight = rootView?.height ?: 0
                        val keyboardHeight = if (scrollViewRoot.keyboardOpen) screenHeight - r.bottom else 0

                        val requiredScrollY = viewBottom + additionalPadding - (screenHeight - keyboardHeight)
                        if (requiredScrollY > 0) {
                            scrollViewRoot.smoothScrollTo(0, requiredScrollY)
                        }
                    }, 500) 
                }
            }

manifest;

android:windowSoftInputMode="adjustResize"
0

There are 0 best solutions below