React-Native 시리즈 5. RN은 팝업 선택 인터페이스와 애니메이션 효과를 실현한다.
8661 단어 ReactNative
우선, 우리가 어떻게 팝업 상자를 실현하는지, 내 쪽은 absolute 절대 포지셔닝을 사용하는데, 탄층의 덮어쓰기,Dialog의 절대 위치를 포함한다.
Dialog의 레이아웃은 여기서 말하지 않겠습니다. flex-box, 상자 모형...
그럼 애니메이션을 다시 한 번 말씀드리겠습니다.
참조: RN 애니메이션 시작 Animated
1. 4
Animated.Value
<Animated.View style={ styles.mask } >
</Animated.View>
<Animated.View style={[styles.tip , {transform: [{
translateY: this.state.offset.interpolate({
inputRange: [0, 1],
outputRange: [height, (height-aHeight -34)]
}),
}]
}]}>
</Animated.View>
나는 여기에 두 개를 만들었는데 하나는 마스크 효과이고 하나는 다이어로그이다.
2. Dialog 스타일 작성
여기서 생략하면 뒤에 있는 전체 코드를 보십시오.
3. 애니메이션 효과
먼저 Dialog의 애니메이션을 표시합니다.
//
in() {
Animated.parallel([
Animated.timing(
this.state.opacity,
{
easing: Easing.linear,
duration: 500,
toValue: 0.8,
}
),
Animated.timing(
this.state.offset,
{
easing: Easing.linear,
duration: 500,
toValue: 1,
}
)
]).start();
}
애니메이션은 일부 보조 함수를 통해 더욱 복잡하게 조합될 수 있다.
sequence
혹은
parallel
(이것들은 각각 여러 개의 애니메이션을 앞뒤로 실행하고 여러 개의 애니메이션을 동시에 실행하는 데 사용된다)
나는 두 개의 애니메이션으로 설계되었기 때문에parallel을 사용하여 그들이 동시에 실행하도록 했다.
duration: 실행 시간
easing: Easing의 열거 값은 다음과 같습니다.
spring //
linear //
easeInEaseOut //
easeIn //
easeOut //
keyboard //
Interpolate 소개
interpolate(config: InterpolationConfigType)
등록 정보를 업데이트하기 전에 값을 보간합니다.예를 들어 0-1을 0-10에 비추다.
여기서 우리는translateY에서 0에서 1, 높이는height에서 (height-aHeight-34)까지 입력하고 간단하게Dialog를 Y방식으로 이동시킨다.
애니메이션을 나타내는 원리를 알게 되면 애니메이션이 사라지는 것이 더욱 간단해진다.
원리: 커버층은 0.8의 투명도에서 맛이 0(표시되지 않음)으로 변하고 높이는 다시 거꾸로 하면 된다(어디서 왔고 어디로 돌아갔는지), 코드는 아래에 보인다.
최종적으로 이루어진 효과는 다음과 같다.
전체 코드는 다음과 같습니다: (여기에Dialog를 구성 요소로 봉하여 사용하려면 페이지에서 직접 가져오고ref방식으로 show 방법을 호출하면 됩니다)
물론 너도 너의 요구에 따라 양식을 수정할 수 있다.여기에는 단지 실현 방안을 설명했을 뿐이다.
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
View,
Image,
Text,
TouchableHighlight,
Animated,
Easing,
Dimensions,
} from 'react-native';
import TimerMixin from 'react-timer-mixin';
const {width, height} = Dimensions.get('window');
const navigatorH = 64; // navigator height
const [aWidth, aHeight] = [300, 214];
const [left, top] = [0, 0];
const [middleLeft, middleTop] = [(width - aWidth) / 2, (height - aHeight) / 2 - navigatorH];
const styles = StyleSheet.create({
container: {
position:"absolute",
width:width,
height:height,
left:left,
top:top,
},
mask: {
justifyContent:"center",
backgroundColor:"#383838",
opacity:0.8,
position:"absolute",
width:width,
height:height,
left:left,
top:top,
},
tip: {
width:aWidth,
height:aHeight,
left:middleLeft,
backgroundColor:"#fff",
alignItems:"center",
justifyContent:"space-between",
},
tipTitleView: {
height:55,
flexDirection:'row',
alignItems:'center',
justifyContent:'center',
},
tipTitleText:{
color:"#999999",
fontSize:14,
},
tipContentView: {
width:aWidth,
borderTopWidth:0.5,
borderColor:"#f0f0f0",
height:45,
flexDirection:'row',
alignItems:'center',
justifyContent:'center',
},
tipText:{
color:"#e6454a",
fontSize:17,
textAlign:"center",
},
button: {
height: 45,
backgroundColor: '#fff',
//borderColor: '#e6454a',
//borderWidth: 1,
//borderRadius: 4,
alignSelf: 'stretch',
justifyContent: 'center',
//marginLeft: 10,
//marginRight: 10,
},
buttonText: {
fontSize:17,
color:"#e6454a",
textAlign:"center",
},
gap:{
height:10,
width:aWidth,
backgroundColor:'#383838',
opacity:0.8,
},
});
//console.log('======');
export default class Alert extends Component {
mixins = [TimerMixin];
parent ={};
constructor(props) {
super(props);
this.state = {
offset: new Animated.Value(0),
opacity: new Animated.Value(0),
title: "",
choose1: "",
choose2: "",
hide: true,
};
}
render() {
if(this.state.hide){
return (<View />)
} else {
return (
<View style={styles.container} >
<Animated.View style={ styles.mask } >
</Animated.View>
<Animated.View style={[styles.tip , {transform: [{
translateY: this.state.offset.interpolate({
inputRange: [0, 1],
outputRange: [height, (height-aHeight -34)]
}),
}]
}]}>
<View style={styles.tipTitleView}>
<Text style={styles.tipTitleText}>{this.state.title}</Text>
</View>
<TouchableHighlight style={styles.tipContentView} underlayColor='#f0f0f0' onPress={this.choose.bind(this,this.state.choose1)}>
<Text style={styles.tipText} >{this.state.choose1}</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.tipContentView} underlayColor='#f0f0f0' onPress={this.choose.bind(this,this.state.choose2)}>
<Text style={styles.tipText} >{this.state.choose2}</Text>
</TouchableHighlight>
<View style={styles.gap}/>
<TouchableHighlight style={styles.button} underlayColor='#f0f0f0' onPress={this.iknow.bind(this)}>
<Text style={styles.buttonText}> </Text>
</TouchableHighlight>
</Animated.View>
</View>
);
}
}
componentDidMount() {
}
//
in() {
Animated.parallel([
Animated.timing(
this.state.opacity,
{
easing: Easing.linear,
duration: 500,
toValue: 0.8,
}
),
Animated.timing(
this.state.offset,
{
easing: Easing.linear,
duration: 500,
toValue: 1,
}
)
]).start();
}
//
out(){
Animated.parallel([
Animated.timing(
this.state.opacity,
{
easing: Easing.linear,
duration: 500,
toValue: 0,
}
),
Animated.timing(
this.state.offset,
{
easing: Easing.linear,
duration: 500,
toValue: 0,
}
)
]).start();
setTimeout(
() => this.setState({hide: true}),
500
);
}
//
iknow(event) {
if(!this.state.hide){
this.out();
}
}
//
choose(msg) {
//console.log(msg);
if(!this.state.hide){
this.out();
this.parent.setState({sex:msg});
}
}
show(title: string, choose1:string,choose2:string ,obj:Object) {
this.parent = obj;
if(this.state.hide){
this.setState({title: title, choose1: choose1, choose2: choose2, hide: false}, this.in);
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[ReactNative][iOS]의 실제 디버깅 및 오프라인 패키지 방식이 글은 React Native에서 iOS 개발의 흔한 디버깅 방식과 오프라인 패키지 개발 방식에 대해 설명합니다.iOS 개발을 한 학우들은 iOS 개발 디버깅은 애플 개발자 계정을 등록해야 한다는 것을 알고 있다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.