我试图去lazycolumn最后一项,因为我有一个lazycolumn和空列表。我做的应用程序是一个聊天机器人应用程序,有机器人消息和用户消息。当机器人给出消息时,它被添加到list
,同时,当用户输入回复时,它被添加到list
,当它被添加到这个list
时,空列表开始填满,lazycolumn也显示出来,但它是一个单独的东西,应该在通信应用中,随着消息的添加,也就是到了屏幕的末尾,屏幕需要向下滑动,我用了scrollToEnd
或者类似的东西来做这个,但我的项目没有看到scrollToEnd
,并给出以下错误Unresolved reference: scrollToEnd
或例如isScrolledToEnd()
当我使用此选项时,我不知道是否应该添加一个单独的项。是否存在依赖项或它们已过时?您能帮助我解决此问题吗
var index = 1
@SuppressLint("CoroutineCreationDuringComposition")
@Composable
fun FirstScreen() {
val list = remember { mutableStateListOf<Message>() }
val UserList = remember { mutableStateListOf<Message>() }
val botList = listOf("Peter", "Francesca", "Luigi", "Igor")
val random = (0..3).random()
val botName: String = botList[random]
val hashMap: HashMap<String, String> = HashMap<String, String>()
val coroutineScope = rememberCoroutineScope()
customBotMessage(message = Message1, list)
Column(modifier = Modifier.fillMaxHeight(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top) {
Image(
painter = painterResource(id = R.drawable.diyetkolik_logo),
contentDescription = "logo",
modifier = Modifier.padding(10.dp)
)
Divider()
val listState = rememberLazyListState()
LazyColumn(modifier = Modifier.fillMaxSize(),
state = listState) {
println("size:"+list.size)
items(list.size) { i ->
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement =
if (list[i].id == RECEIVE_ID)
Arrangement.Start
else
Arrangement.End
) {
if (list[i].id == RECEIVE_ID) {
Item(
message = list[i],
botName,
botcolor,
list,
simpleTextFlag = true,
hashMap,
modifier = Modifier
.padding(
start = 32.dp,
end = 4.dp,
top = 4.dp
),
)
} else {
Item(
message = list[i],
"user",
usercolor,
UserList,
simpleTextFlag = false,
hashMap,
Modifier.padding(
start = 4.dp,
end = 32.dp,
top = 4.dp
)
)
}
}
}
}
val endOfListReached = remember {
derivedStateOf {
listState.isScrolledToEnd() // error occurs Unresolved reference
}
}
// act when end of list reached
LaunchedEffect(endOfListReached) {
// do your stuff
}
}
}
private fun customBotMessage(message: String, list: SnapshotStateList<Message>) {
GlobalScope.launch {
delay(1000)
withContext(Dispatchers.Main) {
list.add(
Message(
message,
RECEIVE_ID,
Timestamp(System.currentTimeMillis()).toString()
)
)
}
}
}
@Composable
fun Item(
message: Message,
person: String,
color: Color,
list: SnapshotStateList<Message>,
simpleTextFlag: Boolean,
hashMap: HashMap<String, String>,
modifier: Modifier
) {
Column(verticalArrangement = Arrangement.Top) {
Card(
modifier = Modifier
.padding(10.dp),
backgroundColor = color,
elevation = 10.dp
) {
Row(
verticalAlignment = Alignment.Top,
modifier = Modifier.padding(3.dp)
) {
Text(
buildAnnotatedString {
withStyle(
style = SpanStyle(
fontWeight = FontWeight.Medium,
color = Color.Black
)
) {
append("$person: ")
}
},
modifier = Modifier
.padding(4.dp)
)
Text(
buildAnnotatedString {
withStyle(
style = SpanStyle(
fontWeight = FontWeight.W900,
color = Color.White//Color(/*0xFF4552B8*/)
)
)
{
append(message.message)
}
}
)
}
}
if (simpleTextFlag)
SimpleText(list = list, hashMap)
}
}
@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
@Composable
fun SimpleText(list: SnapshotStateList<Message>, hashMap: HashMap<String, String>) {
val coroutineScope = rememberCoroutineScope()
val keyboardController = LocalSoftwareKeyboardController.current
val bringIntoViewRequester = remember { BringIntoViewRequester() }
var visible by remember { mutableStateOf(true) }
var text by remember { mutableStateOf("") }
AnimatedVisibility(
visible = visible,
enter = fadeIn() + slideInHorizontally(),
exit = fadeOut() + slideOutHorizontally()
) {
Row(
verticalAlignment = Alignment.Bottom,
horizontalArrangement = Arrangement.End,
modifier = Modifier.bringIntoViewRequester(bringIntoViewRequester)
) {
OutlinedTextField(
modifier = Modifier
.padding(2.dp)
.onFocusEvent { focusState ->
if (focusState.isFocused) {
coroutineScope.launch {
bringIntoViewRequester.bringIntoView()
}
}
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { keyboardController?.hide() }),
value = text,
onValueChange = { text = it },
shape = RoundedCornerShape(12.dp),
label = { Text("send message") })
IconButton(onClick = {
if (text.isNotEmpty()) {
//Adds it to our local list
list.add(
Message(
text,
Constants.SEND_ID,
Timestamp(System.currentTimeMillis()).toString()
)
)
hashMap.put(Messages.listOfMessageKeys[index - 1], text)
customBotMessage(listOfMessages[index], list)
index += 1
visible = false
}
text = ""
}) {
Icon(
modifier = Modifier.padding(2.dp),
painter = painterResource(id = R.drawable.ic_baseline_send_24),
contentDescription = "send message img"
)
}
}
}
}
private fun customBotMessage(message: String, list: SnapshotStateList<Message>) {
GlobalScope.launch {
delay(1000)
withContext(Dispatchers.Main) {
list.add(
Message(
message,
Constants.RECEIVE_ID,
Timestamp(System.currentTimeMillis()).toString()
)
)
}
}
}
我知道这段代码写得很糟糕,你可能很难理解,所以我会解释代码是如何工作的。简单地说,打开的第一个屏幕是FirstScreen,这里定义了一个空列表,这里的空列表指的是FirstScreen中的val list = remember { mutableStateListOf<Message>() }
。首先,我调用customBotMessage
函数与用户交互。并且它添加我准备的消息列表中的第一条消息,当添加到list
时,它进入lazycolumn,并在屏幕上显示为Item
。
当转到Item
时,Item
中有一个消息框,消息框下方有一个文本字段,用户可以在其中输入,如果传入Item
的消息是用户消息,则显示此输入文本字段。我使用FirstScreen中lazycolumn中if
状态中的id
检查了此问题,如果你看一下FirstScreen,你就会明白,当用户在输入文本域中输入一个值时,它会被添加到相同的list
中并显示在屏幕上,但是当消息被添加到list
中时,我希望屏幕向下滚动,正如我上面所说的,我如何在代码中做到这一点?
2条答案
按热度按时间ukdjmx9f1#
函数
listState.isScrolledToEnd()
当前不存在于合成中。从
1.4.0-alpha03
开始,您可以使用**LazyListState#canScrollForward
**检查您是否位于列表末尾。在
1.4.0-alpha03
之前,您必须构建一个自定义函数,如下所示:ttp71kqs2#
请设置您的
LayColumn
,您不需要调用scrollToEnd,您添加到列表中,最新消息将自动显示: