大家好! 今天,我们与您分享认知材料,该材料是专门为“ ReactJS / React Native-developer”课程的学生准备的。
因此,让我们开始吧。
我们都看到了以下输入字段:

标题很大,看起来像一个占位符,直到您专注于输入。 它将变小并上升。
看起来很棒 顺利 无可挑剔。
似乎只有经验丰富的开发人员才能做到这一点,对吗?
好吧,也许这是在React Native出现之前的那个年代,那时人们生活在山洞中并制作各种游戏。 但这已成为过去。
您可以观看视频或继续阅读。 这完全取决于您的喜好。
我们要达到什么目标?
我们正在处理两种选择。
第一种是在没有关注输入字段时。

输入字段内部将显示一个题词,其大小等于文本字段的大小。 颜色暗淡。 这与
placeholder
属性非常相似。
第二种选择,当重点放在输入字段上时。

题词出现在输入字段上方,其大小较小,并且颜色与输入的文本的颜色不同。
最简单的实施
最后,我们可以开始工作了。 到目前为止,没有任何动画。
事实证明,我们有两种UI状态:
- 没有关注该字段以及该字段内的铭文。
- 重点放在字段上,输入字段上方有一个题词。

实际上,我们可以存储是否关注该领域的状态。 然后,根据这种状态,我们可以选择将铭文放置在何处以及要应用哪种样式。
由于铭文必须位于不同的位置,并且我们不希望其影响组件的放置,因此我们将对其进行绝对定位。 为了确保有足够的空间,您必须从上方将缩进添加到包装视图中。
class FloatingLabelInput extends Component { state = { isFocused: false, }; handleFocus = () => this.setState({ isFocused: true }); handleBlur = () => this.setState({ isFocused: false }); render() { const { label, ...props } = this.props; const { isFocused } = this.state; const labelStyle = { position: 'absolute', left: 0, top: !isFocused ? 18 : 0, fontSize: !isFocused ? 20 : 14, color: !isFocused ? '#aaa' : '#000', }; return ( <View style={{ paddingTop: 18 }}> <Text style={labelStyle}> {label} </Text> <TextInput {...props} style={{ height: 26, fontSize: 20, color: '#000', borderBottomWidth: 1, borderBottomColor: '#555' }} onFocus={this.handleFocus} onBlur={this.handleBlur} /> </View> ); } }
<FloatingLabelInput label="Email" value={this.state.value} onChange={this.handleTextChange} />
完成上述步骤后,我们可以实现以下目标:
https://snack.expo.io/Sk006AbdW?session_id=snack-session-JRMksbYK3这是一个很好的起点。 到目前为止,我们还没有动画,但是我们已经可以根据焦点所在的位置更改铭文的位置。
为什么不使用placeholder
?
当然,使用占位符的TextInput
属性似乎很诱人。 但是,这将不起作用,因为我们要控制显示题词的方式,时间和位置。
相反,我们希望标签在焦点位于文本框内时位于文本框内。 并且,当焦点出现在输入字段上时,我们希望它向上移动,只有在使用相同的元素时才能实现。
动画怎么样?
实际上,最简单的部分仍然存在。
由于我们有两个可能有题字的状态,因此我们根据焦点选择一个,并且状态之间的这种过渡的动画非常琐碎。
从本
指南中,我们可以重点介绍以下内容:
Animated.Value
表示是否重点关注字段(1)(0);- 对焦时我们将逐渐将数字更改为(1),否则将更改为(0);
- 以该数字的形式,我们将反映题字的样式:在(0)和(1)中,我们将定义样式,而React Native将自动计算并应用中间样式。 甚至颜色。
实现所有这些并不困难。
Animated.Value
我们将需要在
componentWillMount
进行初始化。
componentWillMount() { this._animatedIsFocused = new Animated.Value(0); }
然后,由于此数字的值应基于是否集中在输入字段上,并且由于我们已经具有此状态信息,因此可以添加
componentDidUpdate
函数,该函数将根据
this.state
更改此数字:
componentDidUpdate() { Animated.timing(this._animatedIsFocused, { toValue: this.state.isFocused ? 1 : 0, duration: 200, }).start(); }
现在,为了以这种方式反映题词的样式,我们只需要进行两项更改:
更改为
Animated.Text
。
而不是使用条件来定义样式,请按以下方式定义它们:
const labelStyle = { position: 'absolute', left: 0, top: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: [18, 0], }), fontSize: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: [20, 14], }), color: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: ['#aaa', '#000'], }), };
https://snack.expo.io/Hk8VCR-dZ?session_id=snack-session-AJ4vulSVw还有一件事
如果在上面的演示中尝试输入某些内容,然后从输入字段中移出焦点,则会看到一些奇怪的内容。

幸运的是,这很容易解决。 我们只需要在代码中更改两行。
我们要检查输入字段是否为空,并且仅当以下两个条件都成立时,才将状态更改为
“未聚焦” :
否则,我们希望应用
“重点突出”的样式,并增加替换标题。
现在我们正在跟踪
输入字段的状态,我们可以使用
this.props
轻松访问其值。
https://snack.expo.io/ByZBAC-dZ?session_id=snack-session-YNZSqhqOC
仅此而已。
免费网络研讨会上见 。