事先,这个问题包含图片,我不熟悉如何发布图片的最佳做法。如果我的帖子做得不好,我没有问题重构。
我正在尝试为实践目的创建设计。而且我对卡的定位有点困难。我相信使用绝对位置应该创建所需的效果并手动调整“顶部”,但它会切断卡的上半部分。
我使用的代码是:
<Animated.View style={animatedStyles}>
<View style={styles.phoneContainer}>
<View style={{ position: "absolute" }}>
<Deck deckColor="#ED29F9" />
<View
style={{
position: "absolute",
bottom: 15
}}
>
<Deck deckColor="red" />
</View>
<View
style={{
position: "absolute",
bottom: 5,
left: 2
}}
>
<Deck deckColor="#FFF5AB" />
</View>
<View
style={{
position: "absolute"
}}
>
<Deck deckColor="#78BDF0" />
</View>
</View>
</View>
</Animated.View>
非常感谢任何帮助或线索。
The component's code is:
const Deck = () => {
return (
<View>
<View style={styles.head} />
<View style={styles.body}>
<View style={styles.bodyContents}>
<View style={styles.circle} />
<View style={styles.text} />
<View style={styles.text} />
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
bodyContents: {
flexDirection: "column",
flex: 0.8,
justifyContent: "space-around",
alignItems: "center"
},
text: {
height: 30,
borderRadius: 5,
width: 100,
backgroundColor: "#d2d2d2"
},
circle: {
borderRadius: 50,
backgroundColor: "#d2d2d2",
height: 50,
width: 50,
marginTop: 20
},
head: {
backgroundColor: "#ED29F9",
flex: 0.2,
width: 250
},
body: {
flex: 0.7,
width: 250,
borderRadius: 4,
borderWidth: 0.5,
borderColor: "#d6d7da",
backgroundColor: "#F7F7F7"
}
});
答案 0 :(得分:0)
这只是建议你找到做你计划的最佳方式。
// this code bellow I was testing in the App.js
import React, { Component } from 'react';
import {View} from 'react-native';
import Deck from './components/Deck';
import ButtonReject from './components/ButtonReject';
import ButtonAccept from './components/ButtonAccept';
import TopBar from './components/Topbar';
export default class App extends Component {
constructor(props){
super(props);
this.state={
//array of decks
decks: [
{
headColor: '#00FA9A',
},
{
headColor: '#8A2BE2',
},
{
headColor: '#1E90FF',
},
{
headColor: '#FFFF00'
},
{
headColor: '#FF6171'
}
],
}
// it's a Map that refer to the Decks Components in the container
this.refDecks = new Map();
}
// Rejects a card
reject(){
// Calls the reject function in the last card in the deck
this.refDecks.get(this.state.decks.length-1).reject();
this.removeCard();
}
// Accepts a card
accept(){
// Calls the accept function in the last card in the deck
this.refDecks.get(this.state.decks.length-1).accept();
// Calls the accept function in the topBar Component (it changes the heart color)
this.topBar.accept();
this.removeCard();
}
// Waits the time of the animation and remove the card
removeCard(){
setTimeout(()=>{
decks = this.state.decks;
decks.splice(0, 1);
this.setState({decks:decks});
},250);
}
renderDeck(){
// render the cards starting of the end (it changes the position props in the Decks, when a card is removed, so all others cards updates their positions in the deck)
return this.state.decks.slice(0).reverse().map((deck,index) =>{
return (
(this.refDecks.set(index, ref))} />
)
})
}
render() {
return (
<View>
<TopBar onRef = {ref =>{this.topBar = ref}} />
<View>
{this.renderDeck()}
</View>
<View style={{justifyContent:'flex-end'}}>
<ButtonReject reject={this.reject.bind(this)} />
<ButtonAccept accept={this.accept.bind(this)} />
</View>
</View>
);
}
}
// fim do App.js
Component => ButtonReject.js
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
TouchableOpacity,
Dimensions
} from 'react-native';
export default class ButtonReject extends Component {
constructor(props){
super(props);
}
onPress() {
this.props.reject();
}
render(){
return (
<View style={styles.circle}>
<TouchableOpacity
onPress={this.onPress.bind(this)}
>
<Text style={styles.textButton}> X
</TouchableOpacity>
</View>
);
}
};
const styles = StyleSheet.create({
circle: {
position: 'absolute',
top: Dimensions.get('window').height - 150,
left: Dimensions.get('window').width -280,
borderRadius: 60,
backgroundColor: "#888888",
height: 60,
width: 60,
marginTop: 20,
alignItems:'center',
justifyContent: 'center'
},
textButton:{
fontSize: 30,
color: '#FFF'
}
});
//fim do ButtonReject.js
Component => TopBar.js
import React, { Component } from 'react';
import {
StyleSheet,
View,
Dimensions
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
export default class TopBar extends Component {
constructor(props){
super(props);
this.state = {
heartColor:'#FFF'
}
}
accept(){
this.setState({heartColor:'#FF1493'});
_this = this;
setTimeout(()=>{
_this.setState({heartColor:'#FFF'});
},1000);
}
changeColor(color){
this.setState({heartColor:color});
}
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(undefined)
}
render(){
return (
<View style={styles.topBar}>
<Icon name="md-heart" style={{left:Dimensions.get('window').width-50,top:20}} size={30} color={this.state.heartColor} />
</View>
);
}
};
const styles = StyleSheet.create({
topBar: {
position: 'absolute',
width: Dimensions.get('window').width,
height: 70,
backgroundColor: "#8A2BE2",
},
textButton:{
fontSize: 30,
color: '#FFF'
}
});
Deck.js
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
Animated,
Dimensions,
TouchableWithoutFeedback
} from 'react-native';
const animationDuration = 250;
export default class Deck extends Component {
constructor(props){
super(props);
this.state= {
headColor:'',
// show or hide the X to close the card, when the card is maximize
maximized: false,
left: new Animated.Value((Dimensions.get('window').width/2)-(150-(this.props.position*7.5))),
top: new Animated.Value((Dimensions.get('window').height/2)-140-(this.props.position*15)),
height: new Animated.Value(300),
width: new Animated.Value(300-(this.props.position*15))
}
}
componentWillReceiveProps (nextProps){
this.initialSize(nextProps);
}
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(undefined)
}
initialSize(props){
Animated.parallel([
Animated.timing(this.state.left, {
toValue: (Dimensions.get('window').width/2)-(150-(props.position*7.5)),
duration: animationDuration
}),
Animated.timing(this.state.top, {
toValue: (Dimensions.get('window').height/2)-140-(props.position*15),
duration: animationDuration
}),
Animated.timing(this.state.height, {
toValue: 300,
duration: animationDuration
}),
Animated.timing(this.state.width, {
toValue: 300-(props.position*15),
duration: animationDuration
}),
]).start();
}
reject(){
Animated.parallel([
Animated.timing(this.state.top, {
toValue: Dimensions.get('window').height-20,
duration: animationDuration
}),
Animated.timing(this.state.height, {
toValue: 3,
duration: animationDuration
}),
Animated.timing(this.state.width, {
toValue: 300-(this.props.position*15)+50,
duration: animationDuration
}),
]).start();
}
accept(){
Animated.parallel([
Animated.timing(this.state.left, {
toValue: Dimensions.get('window').width-50,
duration: animationDuration
}),
Animated.timing(this.state.top, {
toValue: 20,
duration: animationDuration
}),
Animated.timing(this.state.height, {
toValue: 20,
duration: animationDuration
}),
Animated.timing(this.state.width, {
toValue: 20,
duration: animationDuration
}),
]).start();
}
maximize(){
if(this.props.position==1){
Animated.parallel([
Animated.timing(this.state.left, {
toValue: 0,
duration: animationDuration
}),
Animated.timing(this.state.top, {
toValue: 0,
duration: animationDuration
}),
Animated.timing(this.state.height, {
toValue: Dimensions.get('window').height,
duration: animationDuration
}),
Animated.timing(this.state.width, {
toValue: Dimensions.get('window').width,
duration: animationDuration
}),
]).start();
this.setState({maximized:true});
}
}
minimize(){
this.initialSize(this.props);
this.setState({maximized:false});
}
render(){
return (
<Animated.View style={[styles.container,{top:this.state.top,left: this.state.left,height:this.state.height,width:this.state.width}]}>
<TouchableWithoutFeedback onPress={this.maximize.bind(this)}>
<View style={[styles.head,{backgroundColor: this.props.headColor}]}>
{this.state.maximized &&
<View style={styles.containerCloseButton}>
<TouchableWithoutFeedback onPress={this.minimize.bind(this)}>
<Text style={styles.closeButton}>X
</TouchableWithoutFeedback>
</View>
}
</View>
</TouchableWithoutFeedback>
<View style={styles.body}>
<View style={styles.bodyContents}>
<View style={styles.circle} />
<View style={styles.text} />
<View style={styles.text} />
</View>
</View>
</Animated.View>
);
}
};
const styles = StyleSheet.create({
container: {
position: "absolute",
},
bodyContents: {
flexDirection: "column",
flex: 0.8,
justifyContent: "space-around",
alignItems: "center"
},
text: {
height: 30,
borderRadius: 5,
width: 100,
backgroundColor: "#d2d2d2"
},
circle: {
borderRadius: 50,
backgroundColor: "#d2d2d2",
height: 50,
width: 50,
marginTop: 20
},
head: {
flex:1
},
body: {
flex:4,
borderRadius: 4,
borderWidth: 0.5,
borderColor: "#d6d7da",
backgroundColor: "#F7F7F7"
},
containerCloseButton:{
left: Dimensions.get('window').width-30,
top: 20
},
closeButton:{
fontSize: 30,
color: '#FFF'
}
});
您可以让自己很舒服地向我询问有关代码的任何信息。 最诚挚的问候。