|
|
'use strict';
|
|
|
|
|
|
import React, {Component} from 'react';
|
|
|
import ReactNative, {
|
|
|
View,
|
|
|
Text,
|
|
|
Image,
|
|
|
ListView,
|
|
|
TouchableOpacity,
|
|
|
StyleSheet,
|
|
|
Dimensions,
|
|
|
} from 'react-native';
|
|
|
import Immutable, {Map, List} from 'immutable';
|
|
|
|
|
|
import YH_Image from '../../../common/components/YH_Image';
|
|
|
|
|
|
export default class CategorySelector extends Component {
|
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
super(props);
|
|
|
|
|
|
this.dataSource = new ListView.DataSource({
|
|
|
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
|
|
|
});
|
|
|
|
|
|
this.renderRow = this.renderRow.bind(this);
|
|
|
this.scrollToCenter = this.scrollToCenter.bind(this);
|
|
|
|
|
|
this.listView = null;
|
|
|
this.scrollContentWidth = 0;
|
|
|
this.rowPosition = {};
|
|
|
|
|
|
}
|
|
|
|
|
|
scrollToCenter(rowID) {
|
|
|
if (!this.listView) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
let rowLayout = this.rowPosition[rowID];
|
|
|
if (!rowLayout) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
let rowX = rowLayout.x;
|
|
|
let rowWidth = rowLayout.width;
|
|
|
|
|
|
// 位于列表头,且x坐标 < 屏幕x中心距离
|
|
|
if (rowX + rowWidth / 2 < width / 2) {
|
|
|
this.listView && this.listView.scrollTo({x: 0, y: 0, animated: true});
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 位于列表尾,且(容器宽度-x坐标)< 屏幕x中心距离
|
|
|
if ((this.scrollContentWidth - rowX) < width / 2) {
|
|
|
this.listView && this.listView.scrollTo({x: this.scrollContentWidth - width, y: 0, animated: true});
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
|
|
|
let scrollX = rowX + rowWidth / 2 - width / 2;
|
|
|
|
|
|
this.listView && this.listView.scrollTo({x: scrollX, y: 0, animated: true});
|
|
|
|
|
|
}
|
|
|
|
|
|
renderRow(rowData, sectionID, rowID, highlightRow) {
|
|
|
let marginRight = rowID == (this.props.data.size - 1) ? 15 : 0;
|
|
|
let color = rowID == this.props.selectedCategoryIndex ? '#444444' : '#b0b0b0';
|
|
|
return (
|
|
|
<TouchableOpacity
|
|
|
key={'row' + rowID}
|
|
|
activeOpacity={1}
|
|
|
style={styles.rowContainer}
|
|
|
onPress={() => {
|
|
|
this.props.onPressCategory && this.props.onPressCategory(rowData, rowID);
|
|
|
this.scrollToCenter(rowID);
|
|
|
}}
|
|
|
onLayout={(event) => {
|
|
|
this.rowPosition[rowID] = event.nativeEvent.layout;
|
|
|
}}
|
|
|
>
|
|
|
<View style={[styles.categoryContainer, {marginRight, borderColor: color}]}>
|
|
|
<Text style={[styles.categoryName, {color}]} numberOfLines={1}>
|
|
|
{rowData.get('category_name')}
|
|
|
</Text>
|
|
|
</View>
|
|
|
</TouchableOpacity>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
render() {
|
|
|
|
|
|
let data = this.props.data;
|
|
|
|
|
|
return (
|
|
|
<View style={styles.container}>
|
|
|
<ListView
|
|
|
ref={(c) => {
|
|
|
this.listView = c;
|
|
|
}}
|
|
|
enableEmptySections={true}
|
|
|
contentContainerStyle={styles.contentContainer}
|
|
|
dataSource={this.dataSource.cloneWithRows(data.toArray())}
|
|
|
renderRow={this.renderRow}
|
|
|
horizontal={true}
|
|
|
showsHorizontalScrollIndicator={false}
|
|
|
onContentSizeChange={(contentWidth, contentHeight) => {
|
|
|
this.scrollContentWidth = contentWidth;
|
|
|
}}
|
|
|
/>
|
|
|
{data.size > 0 ? <View style={styles.line} /> : null}
|
|
|
</View>
|
|
|
);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
let {width} = Dimensions.get('window');
|
|
|
const DEVICE_WIDTH_RATIO = width / 320;
|
|
|
|
|
|
let imageWidth = Math.floor(width / 2);
|
|
|
let imageHeight = Math.floor(imageWidth * 180 / 375);
|
|
|
|
|
|
let selectorHeight = Math.ceil(45 * DEVICE_WIDTH_RATIO);
|
|
|
|
|
|
selectorHeight = 45;
|
|
|
|
|
|
let styles = StyleSheet.create({
|
|
|
container: {
|
|
|
flexDirection: 'row',
|
|
|
width,
|
|
|
height: selectorHeight,
|
|
|
backgroundColor: 'white',
|
|
|
},
|
|
|
contentContainer: {
|
|
|
|
|
|
},
|
|
|
rowContainer: {
|
|
|
justifyContent: 'center',
|
|
|
|
|
|
},
|
|
|
categoryContainer: {
|
|
|
borderWidth: 1,
|
|
|
borderColor: '#b0b0b0',
|
|
|
borderRadius: 3,
|
|
|
marginLeft: 15,
|
|
|
},
|
|
|
categoryName: {
|
|
|
fontSize: 12,
|
|
|
color: '#b0b0b0',
|
|
|
backgroundColor: 'transparent',
|
|
|
marginLeft: 10,
|
|
|
marginRight: 10,
|
|
|
marginTop: 6,
|
|
|
marginBottom: 6,
|
|
|
},
|
|
|
line: {
|
|
|
position: 'absolute',
|
|
|
width,
|
|
|
height: 1,
|
|
|
left: 0,
|
|
|
bottom: 0,
|
|
|
backgroundColor: '#e5e5e5',
|
|
|
},
|
|
|
}); |
...
|
...
|
|