0

I have a similar search bar I pulled out from this other stackoverflow question. I, however changed lots of it and ended up with a much simpler SearchTextField composable.

@Composable
fun SearchTextField(
    text: String,
    placeholder: String,
    modifier: Modifier = Modifier,
    onTextChange: (String) -> Unit = { },
    onIconClick: () -> Unit = { },
    onFocusChange: (Boolean) -> Unit = { }
) {
    val focusRequester = remember { FocusRequester() }
    val isTextEmpty = text.isEmpty()
    TextField(
        value = text,
        maxLines = 1,
        singleLine = true,
        placeholder = { Text(text = placeholder, overflow = TextOverflow.Visible) },
        onValueChange = onTextChange,
        shape = RoundedCornerShape(percent = 50),
        trailingIcon = { IconDecoration(isTextEmpty = isTextEmpty, onClick = onIconClick) },
        colors = TextFieldDefaults.textFieldColors(
            focusedIndicatorColor = Color.Transparent,
            unfocusedIndicatorColor = Color.Transparent,
            disabledIndicatorColor = Color.Transparent),
        modifier = modifier
            .wrapContentHeight()
            .padding(top = 0.dp, bottom = 0.dp, start = 0.dp, end = 0.dp)
            .onFocusChanged { onFocusChange(it.isFocused) }
            .focusRequester(focusRequester))
}

@Composable
fun IconDecoration(
    isTextEmpty: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier) {
    IconButton(onClick = onClick, modifier = modifier) {
        Icon(
            imageVector = when {
                isTextEmpty -> { Icons.Default.Search }
                else -> { Icons.Default.Close }
            },
            contentDescription = null,
            tint = Color.DarkGray)
    }
}

And from the the previews I get, it looks just as expected:

However, when I try to implement it on a TopAppBar title, it looks like the inner text field is not vertically aligned correctly. Below is an example of the implementation and its preview. I noticed this happens due to the SearchTextField padding modifier. I do need that padding, but there is nowhere to set that in my current TextField, since the current modifier affects the whole composable. Where am I wrong?

@Composable
fun TopBar(
    state: TopBarState,
    modifier: Modifier = Modifier
) {
    TopAppBar(
        modifier = modifier,
        title = {
            SearchTextField(
                text = state.query,
                placeholder = "Search",
                onTextChange = { query ->
                    state.query = query
                    state.suggestions = state.onSearchSuggestions(query)
                },
                onFocusChange = { state.isSearchFocused = it },
                onIconClick = { state.query = "" },
                modifier = Modifier
                    .padding(vertical = 8.dp) // This is causing the overflow
                    .wrapContentHeight(Alignment.Top)) // This won't work
        },
        navigationIcon = {
            NavigationIcon(
                isSearchFocused = state.isSearchFocused,
                onMenuClick = state.onMenuClick,
                onBackClick = { state.isSearchFocused = false })
        },
        actions = {
            ActionItems(
                pages = arrayListOf(Page.Notifications),
                onNavigate = state.onNavigate)
        })
}

@Composable
fun NavigationIcon(
    isSearchFocused: Boolean,
    onMenuClick: () -> Unit,
    onBackClick: () -> Unit
) {
    if(isSearchFocused) {
        IconButton(onClick = onBackClick) {
            Icon(
                imageVector = Icons.Filled.ArrowBack,
                contentDescription = null)
        }
    } else {
        IconButton(onClick = onMenuClick) {
            Icon(
                imageVector = Icons.Filled.Menu,
                contentDescription = null)
        }
    }
}

@Composable
fun ActionItems(
    pages: List<Page>,
    onNavigate: (Page) -> Unit
) {
    pages.forEach { page ->
        IconButton(onClick = { onNavigate(page) }) {
            Icon(
                imageVector = page.icon,
                contentDescription = null)
        }
    }
}

enter image description here

sebsmgzz
  • 361
  • 2
  • 11

0 Answers0