React native 反应本机字体大小的动画锯齿状

React native 反应本机字体大小的动画锯齿状,react-native,animation,interpolation,expo,font-size,React Native,Animation,Interpolation,Expo,Font Size,我使用的是组件,但动画有点锯齿状,无法为字体大小设置动画。我尝试增加动画。计时的toValue,但没有运气。我需要更改哪个部分以使其平滑?请给我一些建议 import React, { Component } from 'react'; import { View, TextInput, Animated, Easing } from 'react-native'; export class FloatingLabelInput extends Component { state = {

我使用的是组件,但动画有点锯齿状,无法为字体大小设置动画。我尝试增加动画。计时的
toValue
,但没有运气。我需要更改哪个部分以使其平滑?请给我一些建议

import React, { Component } from 'react';
import { View, TextInput, Animated, Easing } from 'react-native';

export class FloatingLabelInput extends Component {
  state = {
    isFocused: false,
    value: ''
  };

  componentWillMount() {
    this._animatedIsFocused = new Animated.Value(0);
  }

  handleFocus = () => this.setState({ isFocused: true });
  handleBlur = () => this.setState({ isFocused: false });

  handleTextChange = (newText) => this.setState({ value: newText });

  componentDidUpdate() {
    if (this.state.value == "") {
      Animated.timing(this._animatedIsFocused, {
        toValue: this.state.isFocused ? 1 : 0,
        duration: 200,
      }).start();
    }
  }

  render() {
    const { label, ...props } = this.props;

    const labelBoxStyle = {
      position: 'absolute',
      zIndex: 1,
      paddingHorizontal: 5,
      backgroundColor: '#fff',
      left: 20,
      top: this._animatedIsFocused.interpolate({
        inputRange: [0, 1],
        outputRange: [32, 10],
      })
    };
    const labelStyle = {
      fontSize: this._animatedIsFocused.interpolate({
        inputRange: [0, 1],
        outputRange: [18, 14], // Jaggy animation. Change to [18, 18]
                               // just to see smooth animation.
      }),
      color: this._animatedIsFocused.interpolate({
        inputRange: [0, 1],
        outputRange: ['#aaa', '#3b8c00'],
      }),
    };

    const textInputStyle = {
      height: 50,
      paddingHorizontal: 20,
      fontSize: 18, 
      color: '#000',
      borderWidth: 1, 
      borderColor: '#3b8c00',
      borderRadius: 25
    };

    return (
      <View style={{ paddingTop: 18 }}>
        <Animated.View style={labelBoxStyle}>
          <Animated.Text style={labelStyle}>{label}</Animated.Text>
        </Animated.View>
        <TextInput
          {...props}
          style={textInputStyle}
          onFocus={this.handleFocus}
          onBlur={this.handleBlur}
          value={this.state.value}
          onChangeText={this.handleTextChange}
        />
      </View>
    );
  }
}
import React,{Component}来自'React';
从“react native”导入{View,TextInput,动画,Easing};
导出类FloatingLabelInput扩展组件{
状态={
isFocused:错,
值:“”
};
组件willmount(){
此.u animatedIsFocused=新的Animated.Value(0);
}
handleFocus=()=>this.setState({isFocused:true});
handleBlur=()=>this.setState({isFocused:false});
handleTextChange=(newText)=>this.setState({value:newText});
componentDidUpdate(){
如果(this.state.value==“”){
动画。计时(此为动画){
toValue:this.state.isFocused?1:0,
持续时间:200,
}).start();
}
}
render(){
const{label,…props}=this.props;
常量labelBoxStyle={
位置:'绝对',
zIndex:1,
填充水平面:5,
背景颜色:“#fff”,
左:20,,
上图:这个({
输入范围:[0,1],
输出范围:[32,10],
})
};
常数标签样式={
fontSize:这个。_animatedIsFocused.interpolate({
输入范围:[0,1],
outputRange:[18,14],//锯齿状动画。更改为[18,18]
//只是为了看平滑动画。
}),
颜色:此。_animatedIsFocused.interpolate({
输入范围:[0,1],
输出范围:['aaa','3b8c00'],
}),
};
常量textInputStyle={
身高:50,
水平方向:20,
尺码:18,
颜色:“#000”,
边框宽度:1,
边框颜色:“#3b8c00”,
边界半径:25
};
返回(
{label}
);
}
}

React Native的动画仅支持某些属性的本机动画,例如不透明度和变换。对于这些,您可以通过设置
useNativeDriver:true
来打开它。但是,尝试对
fontSize
使用本机驱动程序会导致本机动画模块不支持
样式属性“fontSize”

如果未设置
useNativeDriver
,或将其设置为
false
,动画将以JavaScript运行,即每次基础动画值更改时(在您的情况下,
\u animatedIsFocused
从0转换为1),它通过网桥将一条消息从本机发送到JS,然后JS需要处理该消息并将消息发送回本机线程。这就是为什么它不平滑

抱歉,没有办法让它使用内置的动画模块在本地运行

幸运的是,有一个很棒的库,名为
react native reanimated
,它通过将所有动画代码移动到native来重新实现动画的运行方式,并为您提供一个JavaScript接口来定义该代码

对于大多数简单的情况,它在v1中有一个动画兼容的界面(请注意,现在有一个重新激活的v2 beta版,它不提供相同的界面,至少现在还没有)。您应该能够更改这行代码:

// import { Animated } from 'react-native'
import Animated, { Easing } from 'react-native-reanimated'
您的动画应该立即开始平稳运行。没有要设置的
useNativeDriver
,因为所有动画都以本机方式运行

请注意,您可能需要在
定时
配置中设置
放松
,例如:

easing:easing.inOut(easing.ease)
您还需要再做一次更改,因为
TextInput
不是从
reanimated
导出的。解决方案很简单,只需创建自己的动画组件:

const animatedtemput=Animated.createAnimatedComponent(TextInput)

您可以在文本或父视图上设置
缩放属性的动画(看起来更平滑)


只是一个想法,但是您是否尝试过从组件中提取样式?现在,您正在render方法中定义所有样式,这将对性能产生影响。我只在渲染方法中保留动画属性。它不起作用,文本不考虑比例
const labelStyle = {
  transform: [
    {
      scale: this._animatedIsFocused.interpolate({
        inputRange: [0, 1],
        outputRange: [1, 0.777],
        extrapolate: 'clamp',
      }),
    },
  ],
}