'LazyColumn with header item in card and remaining items in card

Using compose LazyColumn I would like a card for the header item, and a single card that contains the remaining items.

LazyColumn() {
  item {
    Card() { // header card}
  }

  // would like all items in single card
  Card() { // cannot do this, outside composable function
      items(myItems) { item ->
         // item here
      }
  }
}

Is something like this possible?



Solution 1:[1]

There is no point to have a LazyColumn if you just have 2 items. In this case, use a regular Column with verticalScroll if you need to:

Column(
    modifier = Modifier
        .fillMaxWidth()
        .verticalScroll(
            rememberScrollState()
        ),
) {
    Card(
        modifier = Modifier.fillMaxWidth()
    ) {
        header()
    }
    Card(
        modifier = Modifier.fillMaxWidth()
    ) {
        Column {
            item1()
            item2()
        }
    }
}

Solution 2:[2]

I found sort of a work around for this, but it is not 100%. For instance, it does not have the card attributes. Maybe someone else has some bright ideas. Here's what I have:

@Composable
    fun QuerySearch(
    modifier: Modifier = Modifier,
    query: String,
    label: String,
    onDoneActionClick: () -> Unit = {},
    onClearClick: () -> Unit = {},
    onQueryChanged: (String) -> Unit
) {
    var showClearButton by remember { mutableStateOf(false) }

    TextField(
        modifier = modifier
            .fillMaxWidth()
            .onFocusChanged { focusState ->
            showClearButton = (focusState.isFocused)
        },
        value = query,
        onValueChange = onQueryChanged,
        label = { Text(text = label) },
        textStyle = MaterialTheme.typography.subtitle1,
        singleLine = true,
        trailingIcon = {
        if (showClearButton) {
            IconButton(onClick = { onClearClick() }) {
                Icon(imageVector = Icons.Filled.Close, contentDescription = "Clear")
            }
        }

    },
    keyboardActions = KeyboardActions(onDone = {
        onDoneActionClick()
    }),
    keyboardOptions = KeyboardOptions(
        imeAction = ImeAction.Done,
        keyboardType = KeyboardType.Text
    ),
        colors = TextFieldDefaults.textFieldColors(
            cursorColor = MaterialTheme.colors.secondary,
            textColor = MaterialTheme.colors.onPrimary,
            focusedIndicatorColor = MaterialTheme.colors.secondary,
        )

    )
}

@Composable
fun <T> AutoCompleteTextView(
    modifier: Modifier,
    query: String,
    queryLabel: String,
    onQueryChanged: (String) -> Unit = {},
    predictions: List<T>,
    onDoneActionClick: () -> Unit = {},
    onClearClick: () -> Unit = {},
    onItemClick: (T) -> Unit = {},
    itemContent: @Composable (T) -> Unit = {}
) {

val view = LocalView.current
val lazyListState = rememberLazyListState()
LazyColumn(
    state = lazyListState,
    modifier = modifier.heightIn(max = TextFieldDefaults.MinHeight * 6)
) {
    val lazyListScope = this

    item {
        QuerySearch(
            query = query,
            label = queryLabel,
            onQueryChanged = onQueryChanged,
            onDoneActionClick = {
                view.clearFocus()
                onDoneActionClick()
            },
            onClearClick = {
                onClearClick()
            }
        )
    }

    item {
        if (predictions.count() > 0) {
            Card(
                elevation = 4.dp,
                modifier = Modifier.padding(8.dp),
                backgroundColor = Color.White,
                shape = RoundedCornerShape(8.dp)
            ) {
                lazyListScope.items(predictions) { prediction ->
                    Row(
                        Modifier
                            .fillMaxWidth()
                            .clickable {
                                view.clearFocus()
                                onItemClick(prediction)
                            }
                        .background(MaterialTheme.colors.primaryVariant)
                        ) {
                            itemContent(prediction)
                        }
                    }
                }
            }
        }

    }
}

fun <T> LazyListScope.items(items: List<T>) {
    this.items(items)
}

This results in: address auto complete

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Kristy Welsh