先上官方文檔
InteractionSource
InteractionSource represents a stream of Interactions corresponding to events emitted by a component. These Interactions can be used to change how components appear in different states, such as when a component is pressed or dragged.
翻譯
InteractionSource表示與組件發出的事件相對應的交互流。這些交互可用于更改組件在不同狀態下的顯示方式,例如按下或拖動組件時。
也就是說它應該是用來記錄不同的交互狀態
官方示例簡化
val interactionSource = remember { MutableInteractionSource() }//拖拽
val draggable = Modifier.draggable(interactionSource = interactionSource,orientation = Orientation.Horizontal,state = rememberDraggableState { /* update some business state here */ }
)//點擊
val clickable = Modifier.clickable(interactionSource = interactionSource,indication = LocalIndication.current
) { /* update some business state here */ }//狀態值變化結果
val isDragged by interactionSource.collectIsDraggedAsState()
val isPressed by interactionSource.collectIsPressedAsState()//定義變化后的 text 和 color 下方Box 中 border使用了color Text 使用了text
val (text, color) = when {isDragged && isPressed -> "Dragged and pressed" to Color.RedisDragged -> "Dragged" to Color.GreenisPressed -> "Pressed" to Color.Blue// Default / baseline stateelse -> "Drag me horizontally, or press me!" to Color.Black
}Box(Modifier.fillMaxSize().wrapContentSize().size(width = 240.dp, height = 80.dp)
) {Box(Modifier.fillMaxSize().then(clickable).then(draggable).border(BorderStroke(3.dp, color)).padding(3.dp)) {Text(text, style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),modifier = Modifier.fillMaxSize().wrapContentSize())}
}
將以上代碼放入項目運行效果
- 按下時 文字變化 邊框邊藍
- 拖拽時 文字變化 邊框變綠
官方示例2
以下是省略代碼
val interactions = remember { mutableStateListOf<Interaction>() } //創建了個 集合
//用來記錄 交互事件 添加或從集合中移除LaunchedEffect(interactionSource) {interactionSource.interactions.collect { interaction ->when (interaction) {is PressInteraction.Press -> interactions.add(interaction)is PressInteraction.Release -> interactions.remove(interaction.press)is PressInteraction.Cancel -> interactions.remove(interaction.press)is DragInteraction.Start -> interactions.add(interaction)is DragInteraction.Stop -> interactions.remove(interaction.start)is DragInteraction.Cancel -> interactions.remove(interaction.start)}}}//集合狀態變化 文字變化val text = when (interactions.lastOrNull()) {is DragInteraction.Start -> "Dragged"is PressInteraction.Press -> "Pressed"else -> "No state"}//判斷集合中 交互狀態 顯示不同的效果val pressed = interactions.any { it is PressInteraction.Press }Text(text = if (pressed) "Pressed" else "Not pressed",style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),modifier = Modifier.fillMaxSize().wrapContentSize())
val dragged = interactions.any { it is DragInteraction.Start }Text(text = if (dragged) "Dragged" else "Not dragged",style = LocalTextStyle.current.copy(textAlign = TextAlign.Center),modifier = Modifier.fillMaxSize().wrapContentSize())
效果
使用
前面我們玩過的
TextField
Button
Switch
等組件 都有 interactionSource 屬性
并且
Modifier.indication(
interactionSource = interactionSource,
indication = LocalIndication.current
)
也可以設置interactionSource
下面我們就簡單玩玩它
實現輸入框獲取到焦點時 提示文字的改變
- collectIsDraggedAsState 拖拽交互
- collectIsFocusedAsState 焦點交互
- collectIsHoveredAsState 懸停交互
- collectIsPressedAsState 點擊交互
創建兩個TextField 可以用來切換焦點
直接上代碼吧
val inPut = remember {mutableStateOf("")}val interactionSource = remember { MutableInteractionSource() }//獲取到當前焦點狀態val isFocused by interactionSource.collectIsFocusedAsState()Column(modifier = Modifier.padding(10.dp)) {TextField(value = inPut.value,onValueChange ={inPut.value = it},modifier = Modifier.fillMaxWidth().height(50.dp),shape = CircleShape,colors = TextFieldDefaults.textFieldColors(focusedIndicatorColor = Color.Transparent,disabledIndicatorColor = Color.Transparent,unfocusedIndicatorColor = Color.Transparent,),placeholder = {Text(text = "${if(isFocused)"請輸入內容" else "這是一個提示語"}")},interactionSource = interactionSource,)Spacer(modifier = Modifier.height(20.dp))TextField(value = inPut.value,onValueChange ={inPut.value = it},modifier = Modifier.fillMaxWidth().height(50.dp),shape = CircleShape,colors = TextFieldDefaults.textFieldColors(focusedIndicatorColor = Color.Transparent,disabledIndicatorColor = Color.Transparent,unfocusedIndicatorColor = Color.Transparent,),placeholder = {Text(text = "這是一個提示語")},)}
效果 上邊的TextField 獲取和失去焦點時,文字改變
更多的用法一般是
當TextField 獲取到焦點時邊框或者背景變化 用以表示我們選中了該輸入框
于是 我們包一層
@ExperimentalMaterial3Api
@Composable
fun MyTextField(value: String,onValueChange: (String) -> Unit,modifier: Modifier = Modifier,placeholder: @Composable (() -> Unit)? = null,
) {val interactionSource = remember { MutableInteractionSource() }//獲取到當前焦點狀態val isFocused by interactionSource.collectIsFocusedAsState()val color = when{isFocused -> Color.Redelse -> Color.Black}TextField(value = value,onValueChange = onValueChange,modifier = modifier.border(3.dp,color, shape = CircleShape),shape = CircleShape,colors = TextFieldDefaults.textFieldColors(focusedIndicatorColor = Color.Transparent,disabledIndicatorColor = Color.Transparent,unfocusedIndicatorColor = Color.Transparent,),placeholder = placeholder,interactionSource = interactionSource,)}
然后使用
val inPut = remember {mutableStateOf("")}Column(modifier = Modifier.padding(10.dp)) {MyTextField(value = inPut.value,onValueChange ={inPut.value = it},modifier = Modifier.fillMaxWidth().height(50.dp),placeholder = {Text(text = "這是一個提示語")})Spacer(modifier = Modifier.height(20.dp))MyTextField(value = inPut.value,onValueChange ={inPut.value = it},modifier = Modifier.fillMaxWidth().height(50.dp),placeholder = {Text(text = "這是一個提示語")})}
效果如下