TextFieldBuffer.ChangeList


The ordered list of non-overlapping and discontinuous changes performed on a TextFieldBuffer during the current edit or filter operation. Changes are listed in the order they appear in the text, not the order in which they were made. Overlapping changes are represented as a single change.

Summary

Public functions

TextRange
getOriginalRange(changeIndex: Int)

Returns the range in the original text that was replaced.

Cmn
TextRange
getRange(changeIndex: Int)

Returns the range in the TextFieldBuffer that was changed.

Cmn

Public properties

Int

The number of changes that have been performed.

Cmn

Extension functions

inline Unit

Iterates over all the changes in this ChangeList.

Cmn
inline Unit

Iterates over all the changes in this ChangeList in reverse order.

Cmn

Public functions

getOriginalRange

fun getOriginalRange(changeIndex: Int): TextRange

Returns the range in the original text that was replaced.

getRange

fun getRange(changeIndex: Int): TextRange

Returns the range in the TextFieldBuffer that was changed.

Public properties

changeCount

val changeCountInt

The number of changes that have been performed.

Extension functions

@ExperimentalFoundationApi
inline fun TextFieldBuffer.ChangeList.forEachChange(
    block: (range: TextRange, originalRange: TextRange) -> Unit
): Unit

Iterates over all the changes in this ChangeList.

Changes are iterated by index, so any changes made by block after the current one will be visited by block. block should not make any new changes before the current one or changes will be visited more than once. If you need to make changes, consider using forEachChangeReversed.

import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.forEachChange
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.material.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.text.substring

// Print a log message every time the text is changed.
BasicTextField(
    state = rememberTextFieldState(),
    inputTransformation = {
        changes.forEachChange { sourceRange, replacedLength ->
            val newString = asCharSequence().substring(sourceRange)
            println("""$replacedLength characters were replaced with "$newString"""")
        }
    }
)

forEachChangeReversed

@ExperimentalFoundationApi
inline fun TextFieldBuffer.ChangeList.forEachChangeReversed(
    block: (range: TextRange, originalRange: TextRange) -> Unit
): Unit

Iterates over all the changes in this ChangeList in reverse order.

Changes are iterated by index, so block should not perform any new changes before the current one or changes may be skipped. block may make non-overlapping changes after the current one safely, such changes will not be visited.

import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.delete
import androidx.compose.foundation.text.input.forEachChange
import androidx.compose.foundation.text.input.forEachChangeReversed
import androidx.compose.foundation.text.input.insert
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.material.Text
import androidx.compose.runtime.remember

// Make a text field behave in "insert mode" – inserted text overwrites the text ahead of it
// instead of being inserted.
BasicTextField(
    state = rememberTextFieldState(),
    inputTransformation = {
        changes.forEachChangeReversed { range, originalRange ->
            if (!range.collapsed && originalRange.collapsed) {
                // New text was inserted, delete the text ahead of it.
                delete(
                    range.end.coerceAtMost(length),
                    (range.end + range.length).coerceAtMost(length)
                )
            }
        }
    }
)
See also
forEachChange