Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextField IME padding in LazyColumn , Compose

Problem : TextField (inside lazy column) text goes below the keybaord

Explanation :

I have a LazyColumn that contains a list of items displaying text fields , In the manifest the activity has windowSoftInputMode="adjustResize" and I am also setting the flag WindowCompat.setDecorFitsSystemWindows(window,false) in the onCreate Method before setContent and I want to make text appear above the keyboard at all times for smoother editing experience !

Using Accompanist Library providing Window Insets to give padding to the Box like this

Box(modifier = Modifier.weight(1f).navigationBarsWithImePadding()){
    LazyColumn() {
         items(myItems) { item->
              ItemComposable(item)
         }
    }
}

As you can see , there's navigationBarsWithImePadding on the box , but it does't work since the text goes below the keyboard , I tried setting the modifier on LazyColumn but then it provides padding with the LazyColumn relative to other items outside of the box !

so I tried contentPadding

LazyColumn(contentPadding=insets.ime.toPaddingValues(additionalBottom=insets.navigationBars.bottom.dp)) {
    items(editor.blocks) { block ->
        RenderBlock(block)
    }
}

Again did't work , since the content padding is applied to the last item / or after it , The keyboard goes above the text

Replacing LazyColumn with a simple Column and using a verticalScroll modifier causes the same problem , Because the list can be long vertical scroll becomes a need

like image 790
Waqas Tahir Avatar asked Apr 17 '21 14:04

Waqas Tahir


2 Answers

If you use Column, you can refer to the following code snippet:

Column(
    modifier = Modifier
        // other modifiers
        .verticalScroll(scrollState, reverseScrolling = true)
        .navigationBarsWithImePadding(),
    verticalArrangement = Arrangement.Bottom,
)
like image 115
Halifax Avatar answered Nov 15 '22 23:11

Halifax


Finally I have a solution for it. Just follow these steps below:

Step 1: In your AndroidManifest.xml

 <activity
    ...
    android:windowSoftInputMode="adjustResize">
 </activity>

Step 2: In your Activity

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    WindowCompat.setDecorFitsSystemWindows(window, false)

    setContent {

        AppTheme {

           ProvideWindowInsets(
               windowInsetsAnimationsEnabled = true,
               consumeWindowInsets = false,
           ) {
              // your content
             }
         }
     }

Step 3:

LazyColumn(
  modifier = Modifier
    .navigationBarsWithImePadding()
    .verticalScroll(state = rememberScrollState())
    .height(LocalConfiguration.current.screenHeightDp.dp)
    .fillMaxWidth(),
 ) {
      // your TextField items
   }

Step 4:

 // init your CoroutineScope
 val  coroutineScope = rememberCoroutineScope()

 // init your BringIntoViewRequester
 val  bringIntoViewRequester = BringIntoViewRequester()

 // use them in your TextField modifier
 modifier = Modifier
   /* ... your other modifiers*/
    .bringIntoViewRequester(bringIntoViewRequester)
    .onFocusEvent {
        if (it.isFocused || it.hasFocus) {
            coroutineScope.launch {
                delay(250)
                bringIntoViewRequester.bringIntoView()
            }
        }
    }
}

Hope it helps.

like image 34
Phuong Sala Avatar answered Nov 15 '22 22:11

Phuong Sala