我想在焦点TextInput动画上显示一个取消按钮。 我执行了以下代码,但是在显示焦点时,取消按钮不显示并跟随该框。仅在动画结束后显示。
当显示取消按钮时,它与textinput不在同一行。 我该如何解决?
const { width } = Dimensions.get('window');
const PADDING = 16;
const SEARCH_FULL_WIDTH = width - PADDING * 2; //search_width when unfocused
const SEARCH_SHRINK_WIDTH = width - PADDING - 90; //search_width when focused
class Search extends React.Component {
constructor(props: IProps) {
super(props);
this.state = {
inputLength: new Animated.Value(SEARCH_FULL_WIDTH),
searchBarFocused: false,
}
}
private onFocus = () => {
Animated.timing(this.state.inputLength, {
toValue: SEARCH_SHRINK_WIDTH,
duration: 250,
}).start(() => this.setState({ searchBarFocused: true }));
}
private onBlur = () => {
Animated.timing(this.state.inputLength, {
toValue: SEARCH_FULL_WIDTH,
duration: 250,
}).start(() => this.setState({ searchBarFocused: false }));
}
<View style={styles.searchContainer}>
<Animated.View style={[
styles.search,
{
width: this.state.inputLength,
position: 'absolute',
left: 16,
alignSelf: 'center'
},
searchBarFocused === true ? undefined : { justifyContent: 'center' }
]}>
<Image source={searchIcon} style={styles.image} />
<TextInput
style={styles.searchInput}
....
onBlur={this.onBlur}
onFocus={this.onFocus}
/>
</Animated.View>
{searchBarFocused &&
<Touchable style={styles.cancelSearch} onPress={this.cancelSearch}>
<Text style={styles.cancelSearchText}>Cancel</Text>
</Touchable>
}
</View>
const styles = StyleSheet.create({
searchContainer: {
flexDirection: 'row',
height: 72,
borderBottomColor: SOLITUDE_COLOR,
},
search: {
flex: 1,
flexDirection: 'row',
height: 40,
borderRadius: 6,
},
cancelSearch: {
marginHorizontal: 16,
textAlign: 'center',
justifyContent: 'center'
}
});
gif:当不专心和专注时
答案 0 :(得分:2)
这是您代码的稍作修改的版本。
import React from "react";
import {
Dimensions,
View,
Animated,
TextInput,
TouchableOpacity,
StyleSheet,
} from "react-native";
const { width } = Dimensions.get("window");
const PADDING = 16;
const SEARCH_FULL_WIDTH = width - PADDING * 2; //search_width when unfocused
const SEARCH_SHRINK_WIDTH = width - PADDING - 90; //search_width when focused
const AnimatedTouchable = Animated.createAnimatedComponent(TouchableOpacity);
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
inputLength: new Animated.Value(SEARCH_FULL_WIDTH),
cancelPosition: new Animated.Value(0),
opacity: new Animated.Value(0),
searchBarFocused: false
};
}
onFocus = () => {
Animated.parallel([
Animated.timing(this.state.inputLength, {
toValue: SEARCH_SHRINK_WIDTH,
duration: 250
}),
Animated.timing(this.state.cancelPosition, {
toValue: 16,
duration: 400
}),
Animated.timing(this.state.opacity, {
toValue: 1,
duration: 250
})
]).start();
};
onBlur = () => {
Animated.parallel([
Animated.timing(this.state.inputLength, {
toValue: SEARCH_FULL_WIDTH,
duration: 250
}),
Animated.timing(this.state.cancelPosition, {
toValue: 0,
duration: 250
}),
Animated.timing(this.state.opacity, {
toValue: 0,
duration: 250
})
]).start();
};
render() {
const { searchBarFocused } = this.state;
return (
<View style={styles.searchContainer}>
<Animated.View
style={[
styles.search,
{
width: this.state.inputLength,
position: "absolute",
left: 16,
alignSelf: "center"
},
searchBarFocused === true ? undefined : { justifyContent: "center" }
]}
>
<TextInput
style={styles.searchInput}
onBlur={this.onBlur}
onFocus={this.onFocus}
placeholder="Type something"
/>
</Animated.View>
<AnimatedTouchable
style={[styles.cancelSearch, { right: this.state.cancelPosition }]}
onPress={() => null}
>
<Animated.Text
style={[styles.cancelSearchText, { opacity: this.state.opacity }]}
>
Cancel
</Animated.Text>
</AnimatedTouchable>
</View>
);
}
}
const styles = StyleSheet.create({
searchContainer: {
flexDirection: "row",
height: 72,
borderBottomColor: "#00000033",
paddingTop: 100
},
search: {
flex: 1,
flexDirection: "row",
height: 40,
borderRadius: 6,
backgroundColor: "red"
},
cancelSearch: {
position: "absolute",
marginHorizontal: 16,
textAlign: "center",
justifyContent: "center",
alignSelf: "center"
}
});
答案 1 :(得分:0)
仅在动画完成后才设置searchBarFocused
。由于取消按钮是根据searchBarFocused
有条件渲染的,因此它仅出现在动画的结尾。