今天大概会聊到的范围
- State
- Gesture Modifier
在之前,都只是在介绍比较静态的画面。但今天如果想要和使用者互动时,该如何处理呢?
从最基础的按钮开始,按钮有一个 parameter 是 onClick,这个 onClick lambda 就可以处理最基础的互动。
Button(onClick = {}) {
Text("button")
}
在原先的 Android view system,可以对每一个 View 做 click 。在 Compose 中一样可以做到
Text("button", modifier = Modifier.clickable { })
在任何的 Composable 上,都可以加上 clickable 这个 modifier,一样可以做到点击的互动。另外,还有 combinedClickable
这个 modifier ,可以设定长按、双击之类较少用的点击事件。
Text(
"button",
modifier = Modifier.combinedClickable(
onClick = { },
onLongClick = { },
onDoubleClick = { }
)
)
在与使用者互动之後,可能就会有不同的资料需要显示给 user 。在 Compose function 里,我们可以用一般的 if-else / when 等判断式来决定要显示什麽资料。
var isClicked = false
Column {
if (isClicked) {
// 1.
Text("Click me", modifier = Modifier.clickable { isClicked = true })
} else {
// 2.
Text("Clicked")
}
}
虽然我们在 1 这个 Text 上有设定一个 click 事件,将 isClicked
改成 false。但实际执行起来,会发现点击了没有效果。原因是因为 isClicked
这个变数改变後,不会触发 recomposition。Recomposition 就是 Composable 重新执行 compose 的行为,recomposition 会因为 state 改变而触发。有几个不同的方法可建立 state
// 使用 remember 来建立
val isClickedState = remember { mutableStateOf(false) }
// 使用 delegate
var isClicked by remember { mutableStateOf(false) }
在使用 delegate ( by ) 来建立 state 时,会需要 import androidx.compose.runtime.setValue 和 getVale
要使用时,如果用 delegate 的方式建立的 State,可以直接是为对应的型别赋值。如果用 remember 存放 state 的话,会需要透过 value 的 setter
Text("Click me",
modifier = Modifier.clickable {
isClicked = true
// or
isClickedState.value = true
}
)
当一个 composable 中,有自己控制自己的 State 时,就是一个 Stateful composable。Stateful 的 composable 可以自己处理自己的状态,但同时,外部的元件就没办法控制他(或者说,需要一些 callback 来与外部互动)
相反的 Stateless 的 composable 是不自己处理 State 的 component。这不代表他没有状态,而可能是他的状态是由外部控管的。
@Composable
fun StatelessComponent(isClicked: Boolean, whenClick: () -> Unit ) {
Column {
if (isClicked) {
Text("Click me", modifier = Modifier.clickable { whenClick() })
} else {
Text("Clicked")
}
}
}
将 State 交给外部的作法,称为 state hoisting。透过 state hoisting ,我们可以一层一层将状态提升到最外层,最後由统一个 ViewModel ( 或 Presenter 这类的角色 ) 进行控制。
今天先简单题及了互动与状态 (State),後续还会有更复杂的互动方式(例如 Drag & Drop),State 也会是动画、互动等行为的基础。
Reference:
ax.flatten(): Transform n*m to 1*nm 1-D Array fig...
在撰写Python专案时,时常会遇到需要不同Python版本以及不同版本的Package的问题。建立...
今天的实作内容主要根据网路资源进行。 Django并没有提供官方的社群登入整合模组,在第三方套件上,...
在这30天的比赛中,不知不觉的到最後一天了,虽然中间发生了点小插曲导致没有成功,但我还是希望能照样将...
在这篇文章中,将会介绍 React 提供的 Profiler API。 介绍 React Profi...