Authored by 于良

tab切换优化 review by 盖剑秋

... ... @@ -59,6 +59,7 @@ const ScrollableTabView = React.createClass({
getInitialState() {
return {
currentPage: this.props.initialPage,
currentPageContentHeight: 0,
scrollValue: new Animated.Value(this.props.initialPage),
containerWidth: Dimensions.get('window').width,
sceneKeys: this.newSceneKeys({ currentPage: this.props.initialPage, }),
... ... @@ -110,7 +111,21 @@ const ScrollableTabView = React.createClass({
updateSceneKeys({ page, children = this.props.children, callback = () => {}, }) {
let newKeys = this.newSceneKeys({ previousKeys: this.state.sceneKeys, currentPage: page, children, });
this.setState({currentPage: page, sceneKeys: newKeys, }, callback);
let currentPageContentHeight = 0;
if (this.props.getCurrentPageHeight) {
let currentPageHeight = this.props.getCurrentPageHeight(page);
currentPageContentHeight = currentPageHeight;
// if (currentPageHeight > 0) {
// this.scrollView.setNativeProps({
// style: {
// height: currentPageHeight,
// },
// });
// }
}
this.setState({currentPage: page, sceneKeys: newKeys, currentPageContentHeight: currentPageContentHeight}, callback);
},
newSceneKeys({ previousKeys = [], currentPage = 0, children = this.props.children, }) {
... ... @@ -230,6 +245,7 @@ const ScrollableTabView = React.createClass({
ref: this._children()[currentPage],
from: prevPage,
});
},
_updateScrollValue(value) {
... ... @@ -252,10 +268,6 @@ const ScrollableTabView = React.createClass({
return React.Children.map(children, (child) => child);
},
setNativeProps(nativeProps) {
this._root.setNativeProps(nativeProps);
},
render() {
let overlayTabs = (this.props.tabBarPosition === 'overlayTop' || this.props.tabBarPosition === 'overlayBottom');
let tabBarProps = {
... ... @@ -290,7 +302,9 @@ const ScrollableTabView = React.createClass({
};
}
return <View ref={(c) => { this._root = c; }} style={[styles.container, this.props.style, ]} onLayout={this._handleLayout}>
let heightStyle = this.state.currentPageContentHeight ? {height: this.state.currentPageContentHeight} : null;
return <View style={[styles.container, heightStyle, this.props.style, ]} onLayout={this._handleLayout}>
{this.props.tabBarPosition === 'top' && this.renderTabBar(tabBarProps)}
{this.renderScrollableContent()}
{(this.props.tabBarPosition === 'bottom' || overlayTabs) && this.renderTabBar(tabBarProps)}
... ...
... ... @@ -143,11 +143,13 @@ let styles = StyleSheet.create({
title: {
fontSize: 18,
lineHeight: 28,
paddingTop: -(28 - 18) / 2 - 2,
},
desc: {
fontSize: 14,
lineHeight: 23,
color: '#888888',
paddingTop: -(23 - 14) / 2,
},
thumbs: {
marginTop: 15,
... ...
... ... @@ -29,6 +29,7 @@ const {
let {width, height} = Dimensions.get('window');
let bannerHeight = Math.ceil((363 / 750) * width);
let sectionBarHeight = 41;
export default class Section extends React.Component {
... ... @@ -137,13 +138,14 @@ export default class Section extends React.Component {
this._renderRow = this._renderRow.bind(this);
this._renderSeparator = this._renderSeparator.bind(this);
this._updateScrollValue = this._updateScrollValue.bind(this);
this._updateScrollableTableViewHeight = this._updateScrollableTableViewHeight.bind(this);
this._getCurrentPageHeight = this._getCurrentPageHeight.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2),
});
this.initialPageHeight = height - bannerHeight - sectionBarHeight;
this.currentPage = 0;
this.tabs = ['最新', '热门'];
... ... @@ -196,13 +198,11 @@ export default class Section extends React.Component {
ref={(c) => {
this.scrollableTabView = c;
}}
style={{height: this.state.scrollableTabViewHeight}}
renderTabBar={false}
initialPage={this.currentPage}
onScroll={this._updateScrollValue}
onChangeTab={(tab) => {
this._updateScrollableTableViewHeight(tab.i, true);
}}
getCurrentPageHeight={this._getCurrentPageHeight}
prerenderingSiblingsNumber={Infinity}
>
<SectionList
ref={(c) => {
... ... @@ -214,9 +214,7 @@ export default class Section extends React.Component {
onPressSectionTag={this.props.onPressSectionTag}
onPressComment={this.props.onPressComment}
onPressLike={this.props.onPressLike}
onContentSizeChange={(width, height) => {
this._updateScrollableTableViewHeight(0);
}}
onContentSizeChange={(width, height) => {}}
/>
<SectionList
ref={(c) => {
... ... @@ -228,9 +226,7 @@ export default class Section extends React.Component {
onPressSectionTag={this.props.onPressSectionTag}
onPressComment={this.props.onPressComment}
onPressLike={this.props.onPressLike}
onContentSizeChange={(width, height) => {
this._updateScrollableTableViewHeight(1);
}}
onContentSizeChange={(width, height) => {}}
/>
</ScrollableTabView>
);
... ... @@ -246,7 +242,7 @@ export default class Section extends React.Component {
<SectionTabBar
style={{borderBottomWidth: 0.5, borderBottomColor: '#e0e0e0',}}
tabs={this.tabs}
activeTab={this.state.currentPage}
activeTab={this.currentPage}
scrollValue={this.state.scrollValue}
goToPage={(page) => this._goToPage(page)}
/>
... ... @@ -263,6 +259,10 @@ export default class Section extends React.Component {
}
_goToPage(page) {
this.currentPage = page;
// this.setState({
// currentPage: this.currentPage,
// });
this.scrollableTabView && this.scrollableTabView.goToPage(page);
}
... ... @@ -270,37 +270,20 @@ export default class Section extends React.Component {
this.state.scrollValue.setValue(value);
}
_updateScrollableTableViewHeight(tabIndex, onChangeTab = false) {
if (tabIndex > this.tabs.length - 1) {
return;
}
this.timer = setTimeout(() => {
if (onChangeTab) {
this.currentPage = tabIndex;
this.setState({
currentPage: this.currentPage,
});
}
_getCurrentPageHeight(page) {
let ref = null;
if (tabIndex == 0) {
if (page == 0) {
ref = this.tab1;
} else {
ref = this.tab2;
}
if (!ref) {
return;
return this.initialPageHeight;
}
let height = ref.state.contentHeight;
this.scrollableTabView && this.scrollableTabView.setNativeProps({
style: {
height,
},
});
}, 300);
return height;
}
render() {
... ... @@ -329,7 +312,7 @@ export default class Section extends React.Component {
this.props.onRefresh && this.props.onRefresh();
}}
onEndReached={() => {
this.props.onEndReached && this.props.onEndReached(this.currentPage);
this.props.onEndReached && this.props.onEndReached(this.scrollableTabView.state.currentPage);
}}
renderFooter={() => {
if (endReached) {
... ...
... ... @@ -45,9 +45,9 @@ export default class SectionTabBar extends React.Component {
}
componentWillReceiveProps(nextProps) {
this.setState({
activeTab: nextProps.activeTab
});
// this.setState({
// activeTab: nextProps.activeTab
// });
}
renderTabOption(name, page) {
... ...
... ... @@ -30,6 +30,7 @@ const {
let {width, height} = Dimensions.get('window');
let navbarHeight = (Platform.OS === 'android') ? 50 : 64;
let userBgHieght = Math.ceil((490 / 750) * width);
let sectionBarHeight = 41;
export default class User extends React.Component {
... ... @@ -154,6 +155,7 @@ export default class User extends React.Component {
constructor(props) {
super (props);
this.initialPageHeight = height - userBgHieght - sectionBarHeight;
this.currentPage = 0;
this.tabs = ['我的帖子', '我赞过的', '我的回复'];
this.scrollableTabView = null;
... ... @@ -168,6 +170,7 @@ export default class User extends React.Component {
this._renderSeparator = this._renderSeparator.bind(this);
this._updateHorizontalScrollValue = this._updateHorizontalScrollValue.bind(this);
this._updateVerticalScrollValue = this._updateVerticalScrollValue.bind(this);
this._getCurrentPageHeight = this._getCurrentPageHeight.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
... ... @@ -204,13 +207,11 @@ export default class User extends React.Component {
ref={(c) => {
this.scrollableTabView = c;
}}
renderTabBar={false}
initialPage={this.currentPage}
onScroll={this._updateHorizontalScrollValue}
onChangeTab={(tab) => {
this._updateScrollableTableViewHeight(tab.i, true);
}}
getCurrentPageHeight={this._getCurrentPageHeight}
prerenderingSiblingsNumber={Infinity}
>
<CommunityList
... ... @@ -223,9 +224,7 @@ export default class User extends React.Component {
onPressSectionTag={this.props.onPressSectionTag}
onPressComment={this.props.onPressComment}
onPressLike={this.props.onPressLike}
onContentSizeChange={(width, height) => {
this._updateScrollableTableViewHeight(0);
}}
onContentSizeChange={(width, height) => {}}
/>
<CommunityList
... ... @@ -238,9 +237,7 @@ export default class User extends React.Component {
onPressSectionTag={this.props.onPressSectionTag}
onPressComment={this.props.onPressComment}
onPressLike={this.props.onPressLike}
onContentSizeChange={(width, height) => {
this._updateScrollableTableViewHeight(1);
}}
onContentSizeChange={(width, height) => {}}
/>
<ReplyList
... ... @@ -250,9 +247,7 @@ export default class User extends React.Component {
data={rowData.get('reply')}
onPressAvatar={this.props.onPressAvatar}
onPressReply={this.props.onPressReply}
onContentSizeChange={(width, height) => {
this._updateScrollableTableViewHeight(2);
}}
onContentSizeChange={(width, height) => {}}
/>
</ScrollableTabView>
... ... @@ -296,6 +291,7 @@ export default class User extends React.Component {
}
_goToPage(page) {
this.currentPage = page;
this.scrollableTabView && this.scrollableTabView.goToPage(page);
}
... ... @@ -307,39 +303,22 @@ export default class User extends React.Component {
this.state.scrollValueV.setValue(value);
}
_updateScrollableTableViewHeight(tabIndex, onChangeTab = false) {
if (tabIndex > this.tabs.length - 1) {
return;
}
this.timer = setTimeout(() => {
if (onChangeTab) {
this.currentPage = tabIndex;
this.setState({
currentPage: this.currentPage,
});
}
_getCurrentPageHeight(page) {
let ref = null;
if (tabIndex == 0) {
if (page == 0) {
ref = this.tab1;
} else if (tabIndex == 1) {
} else if (page == 1) {
ref = this.tab2;
} else {
ref = this.tab3;
}
if (!ref) {
return;
return this.initialPageHeight;
}
let height = ref.state.contentHeight;
this.scrollableTabView && this.scrollableTabView.setNativeProps({
style: {
height,
},
});
}, 300);
return height;
}
render() {
... ...