Jetpack Compose AutoComplete SelectBar

Faysalgluma
3 min readJul 25, 2024

--

Hello everyone, I hope you’re well? and welcome to this new tutorial which explains how to create an auto complete selectBar (or Spinner in android language) with Jetpack Compose. This will allow us to select an item from a list with the added functionality of auto complete.

Without getting too chatty, let’s move on to the creation of our class (Spinner.kt I’ve named it) which will create the component (named AutoCompleteSelectBar) responsible for managing our SelectBar.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.KeyboardArrowDown
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.toSize
import com.groupec.selectbarsampleapp.ui.theme.SelectBarSampleAppTheme


@Composable
fun AutoCompleteSelectBar(entries: List<String>) {

var itemElement by remember { mutableStateOf("") }
val heightTextFields by remember { mutableStateOf(55.dp) }
var textFieldSize by remember { mutableStateOf(Size.Zero) }
var expanded by remember { mutableStateOf(false) }
val interactionSource = remember { MutableInteractionSource() }

Column(
modifier = Modifier
.padding(30.dp)
.fillMaxWidth()
.clickable(
interactionSource = interactionSource,
indication = null,
onClick = {
expanded = false
}
)
) {

Text(
text = "Words",
style = MaterialTheme.typography.titleSmall,
color = Color.Black
)

Column(modifier = Modifier.fillMaxWidth()) {
TextField(
modifier = Modifier
.fillMaxWidth()
.height(heightTextFields)
.border(
width = 1.5.dp,
color = Color.Black,
shape = RoundedCornerShape(8.dp)
)
.onGloballyPositioned { coordinates ->
textFieldSize = coordinates.size.toSize()
},
value = itemElement,
onValueChange = {
itemElement = it
expanded = true
},
// Perform action when the TextField is clicked
interactionSource = remember { MutableInteractionSource() }
.also { interactionSource ->
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
if (interaction is PressInteraction.Release) {
expanded = !expanded
}
}
}
},
placeholder = { Text("Enter word") },
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
disabledContainerColor = Color.Transparent,
cursorColor = Color.Black,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
),
textStyle = TextStyle(
color = Color.Black,
fontSize = 16.sp
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done
),
singleLine = true,
trailingIcon = {
Icon(
modifier = Modifier.size(24.dp),
imageVector = Icons.Rounded.KeyboardArrowDown,
contentDescription = "arrow",
tint = Color.Black
)
}
)

AnimatedVisibility(visible = expanded) {
Card(
modifier = Modifier
.width(textFieldSize.width.dp),
shape = RoundedCornerShape(8.dp)
/* colors = CardDefaults.cardColors(
containerColor = Color.Transparent
)*/
) {
LazyColumn(
modifier = Modifier.heightIn(max = 200.dp),
) {

if (itemElement.isNotEmpty()) {
items(
entries.filter {
it.lowercase().contains(itemElement.lowercase())
}.sorted()
) {
ItemElement(title = it) { title ->
itemElement = title
expanded = false
}
}
} else {
items(
entries.sorted()
) {
ItemElement(title = it) { title ->
itemElement = title
expanded = false
}
}
}

}

}
}
}
}
}

@Composable
fun ItemElement(
title: String,
onSelect: (String) -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
onSelect(title)
}
.padding(vertical = 12.dp, horizontal = 15.dp)
) {
Text(text = title, fontSize = 16.sp)
}
}

And now we can call our AutoCompleteSelectBar component from our MainActivity by passing it a static data input.

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
SelectBarSampleAppTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
AutoCompleteSelectBar(entries = getWords())
}

fun getWords() = listOf(
"air",
"rain",
"chair",
"hair",
"fair",
"pair",
"stair",
"snail",
"train",
"chain",
"paint",
"main",
"brain",
"said",
"laid",
"plaid",
"afraid",
"daily",
"fail",
"jail"
)

Thank you for following this quick tutorial. Don’t hesitate to give me a thumbs-up and also leave comments if you have any questions. Thanks you!

Github Link : https://github.com/faysalluma/SelectBarSampleApp

--

--