Highlight filtered Text in Compose While Using Search
Jetpack Compose is a modern declarative UI Toolkit for Android. The best way to learn any new technology is to build something.
There is one kind of requirement Highlight filtered Text from List when we are using search. This artical is about to solve this problem in Compose.
Now, we will take an example of Dog Breed List where user can search dog breed and highlighted matching name from list.
we will go for the following steps in order to achieve desired results…
- Make a search view
- Use LazyList to show Dog list
- Get substring list which matches with the Search Text
- Display of highlighted text
Compose Components used for this requirement are: TextField, LazyColumn, buildAnnotatedString
1. Make a Search View
@Composable
fun SearchView(
searchText: String,
onSearchTextChange: (String) -> Unit
) {
TextField(
value = searchText,
onValueChange = onSearchTextChange,
trailingIcon = {
Icon(Icons.Default.Search, contentDescription = "")
},
label = { Text(text = "Search here ...") },
singleLine = true,
modifier = Modifier.fillMaxWidth()
)
}
We create SearchView using TextField where user can enter text.
2. Use LazyList to show Dog list
@Composable
fun ListDataView(
searchText: String,
dogList: List<DogModel>
) {
LazyColumn {
itemsIndexed(dogList) { _, item ->
DogItemCard(searchText = searchText, itemName = item)
}
}
}
With the help of LazyColumn we create vertical list which shows Dog list
3. Get substring list which matches with the Search Text
private fun getSubStrings(subString: String, text: String): List<IntRange> {
return subString.toRegex()
.findAll(text)
.map { it.range }
.toList()
}
this function is returning the list with range which matches with search text. Now, we move to last step to highlight the text.
4. Display of highlighted text
@Composable
fun DogItemCard(searchText: String, itemName: DogModel) {
val subStrings = getSubStrings(searchText.lowercase(), itemName.name.lowercase())
Card(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
elevation = 2.dp,
backgroundColor = Color.White,
shape = Shapes.small
) {
Text(
text = buildAnnotatedString {
append(itemName.name)
addStyle(
style = SpanStyle(
color = if (searchText.isNotEmpty()) Color.LightGray else Color.DarkGray
),
start = 0,
end = itemName.name.length
)
if (searchText.isNotEmpty()) {
for (subStringRange in subStrings) {
addStyle(
style = SpanStyle(Color.Black),
start = subStringRange.first,
end = subStringRange.last + 1
)
}
}
},
modifier = Modifier.padding(6.dp)
)
}
}
here we used buildAnnotatedString{} to achive this.
git code link: https://github.com/kamydeep00178/ComposeSearch
for more info about buildAnnotatedString{} check the link below
https://developer.android.com/reference/kotlin/androidx/compose/ui/text/ParagraphStyle
Thanks for reading, and I’ll come again with new learnings soon