以Toast banner形式显示一些状态信息,为了更友好,加上动画效果。
注意第一次得到layout需要initBanner,否则showBanner的效果坐标不对。
也就是实际上上先收起来,再滑出来。
代码如下,banner内容自定义即可。
import React from 'react';
import {
StyleSheet,
Text, View, TouchableHighlight,
Animated
} from 'react-native';
export default class AboutComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
bannerHeight: 0
};
this.position = new Animated.ValueXY(0, 0)
}
moveBanner = (duration, yPos) => {
Animated.timing(this.position, {
useNativeDriver: false,
duration: duration,
toValue: { x: 0, y: yPos }
}).start()
}
initBanner = () => {
this.moveBanner(1, 0 - this.state.bannerHeight);
}
showBanner = () => {
this.moveBanner(500, 0);
}
hideBanner = () => {
this.moveBanner(500, 0 - this.state.bannerHeight);
}
onBannerLayout = (e) => {
this.setState({
bannerHeight: e.nativeEvent.layout.height,
}, () => {
this.initBanner();
});
}
render() {
return (
Banner Message
Content
this.hideBanner()} >
Hide Banner
this.showBanner()} >
Show Banner
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
},
button: {
alignSelf: 'center',
color: 'blue',
fontSize: 20,
},
square: {
backgroundColor: 'red',
padding: 20,
alignSelf: 'center',
width: '100%',
}
});
改进版(自适应高度)
import React from 'react';
import {
StyleSheet,
Text, View, TouchableHighlight,
Animated
} from 'react-native';
const bannerMargin = 10;
export default class BannerTestComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
message: '',
makeBannerBackground: true,
marginAnimation: new Animated.Value(0),
};
this.displayBanner = false;
this.bannerHeight = 0;
this.messages = [
"Banner\nBanner\n\Banner",
"Simple one line message",
"Two lines message.\nTwo lines message.\n"
];
this.count = 0
}
moveBanner = (duration, marginTop) => {
console.log(`moveBanner ${duration} ${marginTop}`);
Animated.timing(
this.state.marginAnimation, {
useNativeDriver: false,
toValue: marginTop,
duration
}).start();
}
initBanner = () => {
console.log('initBanner');
this.moveBanner(0, 0 - this.bannerHeight);
}
showBanner = () => {
console.log('showBanner');
this.count += 1;
const message = this.messages[this.count % this.messages.length];
this.displayBanner = true;
this.setState({
message,
});
}
hideBanner = () => {
console.log('hideBanner');
this.displayBanner = false;
this.moveBanner(500, 0 - this.bannerHeight);
setTimeout(() => {
this.moveBanner(0, 0);
this.setState({
message: '',
makeBannerBackground: true
});
}, 600);
}
onBannerLayout = (e) => {
const bannerHeight = e.nativeEvent.layout.height;
console.log(`onBannerLayout ${bannerHeight}`);
if (bannerHeight > 0 && this.displayBanner) {
console.log(`onBannerLayout 2 ${bannerHeight}`);
this.bannerHeight = bannerHeight + bannerMargin * 2;
this.setState({
makeBannerBackground: false
});
this.initBanner();
setTimeout(() => {
this.moveBanner(500, 0)
}, 1);
}
}
render() {
console.log('Render')
return (
{
this.displayBanner && (
{this.state.message}
)
}
Content
this.hideBanner()} >
Hide Banner
this.showBanner('Banner Message\nBanner Message')} >
Show Banner
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
},
button: {
alignSelf: 'center',
color: 'blue',
fontSize: 20,
},
square: {
backgroundColor: 'red',
margin: bannerMargin,
alignSelf: 'center',
width: '100%',
}
});