Browse Source

feat: support go to detail view of a topic by pressing in the topic list view

pull/1/head
kdxcxs 4 years ago
parent
commit
b485273576
  1. 2
      README.md
  2. 14
      src/component/YooForumTopic.js
  3. 58
      src/ui/YooForumTopicUI.js
  4. 84
      src/ui/YooForumUI.js

2
README.md

@ -15,4 +15,6 @@
- [ ] 在启动时检测是否已登录
- [ ] Splash 检测网络出错后在 Splash UI 中显示错误并不跳转
- [ ] Forum 初始化失败后 UI 显示错误信息
- [ ] 当数据获取完成后通过动画转到话题列表
- [ ] 解决当动画进行时点击话题标题动画会被打断的问题

14
src/component/YooForumTopic.js

@ -0,0 +1,14 @@
import React, {Component} from 'react';
import YooForumTopicUI from '../ui/YooForumTopicUI';
export default class YooForumTopic extends Component {
render() {
return (
<YooForumTopicUI
topic={this.props.topic}
showDetail={this.props.showDetail}
hideDetail={this.props.hideDetail}
/>
);
}
}

58
src/ui/YooForumTopicUI.js

@ -1,25 +1,69 @@
import React, {Component} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import React, {Component, createRef} from 'react';
import {
Animated,
View,
Text,
StyleSheet,
Pressable,
Dimensions,
} from 'react-native';
const screenWidth = Dimensions.get('window').width;
const styles = StyleSheet.create({
container: {
borderWidth: 1,
backgroundColor: 'mintcream',
borderRadius: 8,
padding: 16,
margin: 8,
width: screenWidth - 16,
},
title: {
fontSize: 36,
fontSize: 24,
},
owner: {
fontSize: 24,
fontSize: 16,
},
});
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
export default class YooForumTopicUI extends Component {
constructor(props) {
super(props);
this.state = {
detailShowing: false,
layoutY: 0,
translate: new Animated.ValueXY({x: 0, y: 0}),
};
this.topicHeaderRef = createRef();
this.onPress = this.onPress.bind(this);
}
onPress() {
if (!this.state.detailShowing) {
this.setState({detailShowing: true});
this.props.showDetail(this);
} else {
this.setState({detailShowing: false});
this.props.hideDetail(this);
}
}
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>{this.props.topic.title}</Text>
<AnimatedPressable
style={[
styles.container,
{transform: this.state.translate.getTranslateTransform()},
]}
onPress={this.onPress}
onLayout={(event) => {
this.setState({layoutY: event.nativeEvent.layout.y});
}}>
<View ref={this.topicHeaderRef}>
<Text style={styles.owner}>{this.props.topic.owner}</Text>
<Text style={styles.title}>{this.props.topic.title}</Text>
</View>
</AnimatedPressable>
);
}
}

84
src/ui/YooForumUI.js

@ -6,13 +6,21 @@ import {
StyleSheet,
ActivityIndicator,
Image,
Animated,
Dimensions,
} from 'react-native';
import YooForumTopicUI from './YooForumTopicUI';
import YooForumTopic from '../component/YooForumTopic';
const screenWidth = Dimensions.get('window').width;
const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView);
const styles = StyleSheet.create({
container: {
width: screenWidth * 2,
},
hintContainer: {
flex: 1,
alignItems: 'center',
left: -screenWidth / 2,
},
logo: {
marginTop: 120,
@ -30,12 +38,80 @@ const styles = StyleSheet.create({
});
export default class YooForumUI extends Component {
constructor(props) {
super(props);
this.state = {
scrollEnabled: true,
currentPosition: 0,
translateX: new Animated.Value(0),
};
this.showDetail = this.showDetail.bind(this);
this.hideDetail = this.hideDetail.bind(this);
}
showDetail(topicRef) {
this.setState({scrollEnabled: false});
Animated.parallel([
Animated.timing(topicRef.state.translate, {
toValue: {
x: screenWidth,
y: this.state.currentPosition - topicRef.state.layoutY + 8,
},
duration: 500,
useNativeDriver: true,
}),
Animated.timing(this.state.translateX, {
toValue: -screenWidth,
duration: 500,
useNativeDriver: true,
}),
]).start();
}
hideDetail(topicRef) {
this.setState({scrollEnabled: true});
Animated.parallel([
Animated.timing(topicRef.state.translate, {
toValue: {
x: 0,
y: 0,
},
duration: 500,
useNativeDriver: true,
}),
Animated.timing(this.state.translateX, {
toValue: 0,
duration: 500,
useNativeDriver: true,
}),
]).start();
}
render() {
return (
<ScrollView>
<AnimatedScrollView
style={[
styles.container,
{
transform: [
{
translateX: this.state.translateX,
},
],
},
]}
scrollEnabled={this.state.scrollEnabled}
onScroll={(event) =>
this.setState({currentPosition: event.nativeEvent.contentOffset.y})
}>
{this.props.hint === '' ? (
this.props.topics.map((topic, key) => (
<YooForumTopicUI topic={topic} key={key} />
<YooForumTopic
key={key}
topic={topic}
showDetail={this.showDetail}
hideDetail={this.hideDetail}
/>
))
) : (
<View style={styles.hintContainer}>
@ -51,7 +127,7 @@ export default class YooForumUI extends Component {
/>
</View>
)}
</ScrollView>
</AnimatedScrollView>
);
}
}

Loading…
Cancel
Save