Skip to content

Commit 4e10807

Browse files
committed
release 3.3.0
1 parent fac8453 commit 4e10807

File tree

7 files changed

+434
-3
lines changed

7 files changed

+434
-3
lines changed

.gitignore

-3
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,3 @@ freeline_project_description.json
186186

187187
# Demo
188188
Demo/mov
189-
190-
# Example
191-
Example/src

Example/src/controlTab/index.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from 'react'
2+
import { Platform, SegmentedControlIOS } from 'react-native'
3+
import { Button, Text, View } from 'native-base'
4+
5+
export default (props) => {
6+
this.props = props
7+
8+
if (Platform.OS === 'ios') {
9+
return (
10+
<SegmentedControlIOS
11+
style={{ flex: 0.7 }}
12+
values={['list', 'grid']}
13+
tintColor="#57a8f5"
14+
selectedIndex={this.props.layout === 'list' ? 0 : 1}
15+
onChange={this.props.onChangeLayout}
16+
/>
17+
)
18+
}
19+
return (
20+
<View style={{
21+
flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center'
22+
}}
23+
>
24+
<Button
25+
title="list"
26+
small
27+
light={this.props.layout !== 'list'}
28+
onPress={() => this.props.onChangeLayout({ nativeEvent: { selectedSegmentIndex: 0 } })}
29+
style={{
30+
width: 150,
31+
justifyContent: 'center',
32+
borderTopLeftRadius: 5,
33+
borderBottomLeftRadius: 5
34+
}}
35+
>
36+
<Text style={{ color: this.props.layout === 'list' ? 'white' : 'black' }}>List</Text>
37+
</Button>
38+
<Button
39+
title="grid"
40+
small
41+
light={this.props.layout !== 'grid'}
42+
onPress={() => this.props.onChangeLayout({ nativeEvent: { selectedSegmentIndex: 1 } })}
43+
style={{
44+
width: 150,
45+
justifyContent: 'center',
46+
borderTopRightRadius: 5,
47+
borderBottomRightRadius: 5
48+
}}
49+
>
50+
<Text style={{ color: this.props.layout === 'grid' ? 'white' : 'black' }}>Grid</Text>
51+
</Button>
52+
</View>
53+
)
54+
}

Example/src/index.js

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import React, { Component } from 'react'
2+
import { Alert, Dimensions, Platform, View } from 'react-native'
3+
import { Button, Header, Icon, Input, Item, Left, Right, Text } from 'native-base'
4+
import UltimateListView from 'react-native-ultimate-listview'
5+
// import { UltimateListView } from '../lib/index'
6+
import styles from './styles'
7+
import LoadingSpinner from './loadingSpinner'
8+
import ControlTab from './controlTab'
9+
import FlatListItem from './itemContainer/flatListItem'
10+
import FlatListGrid from './itemContainer/flatListGrid'
11+
12+
const { width, height } = Dimensions.get('window')
13+
export default class Example extends Component {
14+
constructor(props) {
15+
super(props)
16+
this.state = {
17+
layout: 'list',
18+
text: ''
19+
}
20+
}
21+
22+
onFetch = async (page = 1, startFetch, abortFetch) => {
23+
try {
24+
// This is required to determinate whether the first loading list is all loaded.
25+
let pageLimit = 24
26+
if (this.state.layout === 'grid') pageLimit = 60
27+
const skip = (page - 1) * pageLimit
28+
29+
// Generate dummy data
30+
let rowData = Array.from({ length: pageLimit }, (value, index) => `item -> ${index + skip}`)
31+
32+
// Simulate the end of the list if there is no more data returned from the server
33+
if (page === 10) {
34+
rowData = []
35+
}
36+
37+
// Simulate the network loading in ES7 syntax (async/await)
38+
await this.sleep(2000)
39+
startFetch(rowData, pageLimit)
40+
} catch (err) {
41+
abortFetch() // manually stop the refresh or pagination if it encounters network error
42+
console.log(err)
43+
}
44+
}
45+
46+
onChangeLayout = (event) => {
47+
this.setState({ text: '' })
48+
switch (event.nativeEvent.selectedSegmentIndex) {
49+
case 0:
50+
this.setState({ layout: 'list' })
51+
break
52+
case 1:
53+
this.setState({ layout: 'grid' })
54+
break
55+
default:
56+
break
57+
}
58+
}
59+
60+
onChangeScrollToIndex = (num) => {
61+
this.setState({ text: num })
62+
let index = num
63+
if (this.state.layout === 'grid') {
64+
index = num / 3
65+
}
66+
try {
67+
this.listView.scrollToIndex({ viewPosition: 0, index: Math.floor(index) })
68+
} catch (err) {
69+
console.warn(err)
70+
}
71+
}
72+
73+
onPressItem = (type, index, item) => {
74+
Alert.alert(type, `You're pressing on ${item}`)
75+
}
76+
77+
sleep = time => new Promise(resolve => setTimeout(() => resolve(), time))
78+
79+
renderItem = (item, index, separator) => {
80+
if (this.state.layout === 'list') {
81+
return (
82+
<FlatListItem item={item} index={index} onPress={this.onPressItem} />
83+
)
84+
} else if (this.state.layout === 'grid') {
85+
return (
86+
<FlatListGrid item={item} index={index} onPress={this.onPressItem} />
87+
)
88+
}
89+
return null
90+
}
91+
92+
renderControlTab = () => (
93+
<ControlTab
94+
layout={this.state.layout}
95+
onChangeLayout={this.onChangeLayout}
96+
/>
97+
)
98+
99+
renderHeader = () => (
100+
<View>
101+
<View style={styles.header}>
102+
<Text style={{ textAlign: 'center' }}>I am the Header View, you can put some Instructions or Ads Banner here!
103+
</Text>
104+
</View>
105+
<View style={styles.headerSegment}>
106+
<Left style={{ flex: 0.15 }} />
107+
{this.renderControlTab()}
108+
<Right style={{ flex: 0.15 }} />
109+
</View>
110+
</View>
111+
)
112+
113+
renderPaginationFetchingView = () => (
114+
<LoadingSpinner height={height * 0.2} text="loading..." />
115+
)
116+
117+
render() {
118+
return (
119+
<View style={styles.container}>
120+
<Header searchBar rounded>
121+
<Item style={{ backgroundColor: 'lightgray', borderRadius: 5 }}>
122+
<Icon name="ios-search" />
123+
<Input placeholder="Search" onChangeText={this.onChangeScrollToIndex} value={this.state.text} />
124+
</Item>
125+
</Header>
126+
<UltimateListView
127+
ref={ref => this.listView = ref}
128+
key={this.state.layout} // this is important to distinguish different FlatList, default is numColumns
129+
onFetch={this.onFetch}
130+
keyExtractor={(item, index) => `${index} - ${item}`} // this is required when you are using FlatList
131+
refreshableMode="advanced" // basic or advanced
132+
133+
item={this.renderItem} // this takes three params (item, index, separator)
134+
numColumns={this.state.layout === 'list' ? 1 : 3} // to use grid layout, simply set gridColumn > 1
135+
136+
// ----Extra Config----
137+
displayDate
138+
header={this.renderHeader}
139+
paginationFetchingView={this.renderPaginationFetchingView}
140+
// sectionHeaderView={this.renderSectionHeaderView} //not supported on FlatList
141+
// paginationFetchingView={this.renderPaginationFetchingView}
142+
// paginationAllLoadedView={this.renderPaginationAllLoadedView}
143+
// paginationWaitingView={this.renderPaginationWaitingView}
144+
// emptyView={this.renderEmptyView}
145+
// separator={this.renderSeparatorView}
146+
147+
// new props on v3.2.0
148+
arrowImageStyle={{ width: 20, height: 20, resizeMode: 'contain' }}
149+
dateStyle={{ color: 'lightgray' }}
150+
refreshViewStyle={Platform.OS === 'ios' ? { height: 80, top: -80 } : { height: 80 }}
151+
refreshViewHeight={80}
152+
/>
153+
</View>
154+
)
155+
}
156+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React, { PureComponent } from 'react'
2+
import { StyleSheet, View, Alert, TouchableOpacity, Image, TouchableHighlight, Dimensions } from 'react-native'
3+
import { Button, ListItem, Left, Right, Body, Thumbnail, Text, Icon } from 'native-base'
4+
import styles from '../styles'
5+
6+
const logo = require('../../img/default-portrait.png')
7+
8+
const { width, height } = Dimensions.get('window')
9+
export default class Example extends PureComponent {
10+
constructor(props) {
11+
super(props)
12+
}
13+
14+
render() {
15+
const rowID = this.props.index
16+
const rowData = this.props.item
17+
return (
18+
<TouchableOpacity onPress={() => this.props.onPress('GridView', rowID, rowData)}>
19+
<View style={{ margin: 0.5, width: width / 3, paddingBottom: 15 }}>
20+
<Thumbnail square source={logo} style={styles.gridThumb} />
21+
<Text style={styles.gridText}>ID: {rowID}</Text>
22+
<Text style={styles.gridText}>{rowData}</Text>
23+
</View>
24+
</TouchableOpacity>
25+
)
26+
}
27+
}
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React, { PureComponent } from 'react'
2+
import { StyleSheet, View, Alert, TouchableOpacity, Image, TouchableHighlight } from 'react-native'
3+
import { Button, ListItem, Left, Right, Body, Thumbnail, Text, Icon } from 'native-base'
4+
import styles from '../styles'
5+
6+
const logo = require('../../img/default-portrait.png')
7+
8+
export default class Example extends PureComponent {
9+
constructor(props) {
10+
super(props)
11+
}
12+
13+
render() {
14+
const rowID = this.props.index
15+
const rowData = this.props.item
16+
return (
17+
<ListItem thumbnail>
18+
<Left>
19+
<Thumbnail square source={logo} style={styles.thumb} />
20+
</Left>
21+
<Body style={{ borderBottomWidth: 0 }}>
22+
<Text>RowID: {rowID}</Text>
23+
<Text note>Data: {rowData}</Text>
24+
</Body>
25+
<Right style={{ borderBottomWidth: 0 }}>
26+
<View style={styles.rightBtnGroup}>
27+
<Button
28+
small
29+
transparent
30+
title="view"
31+
onPress={() => this.props.onPress('chat', rowID, rowData)}
32+
style={styles.rightBtn}
33+
>
34+
<Icon name="chatbubbles" style={styles.rightBtnIcon} />
35+
</Button>
36+
<Button
37+
small
38+
transparent
39+
title="view"
40+
onPress={() => this.props.onPress('like', rowID, rowData)}
41+
style={styles.rightBtn}
42+
>
43+
<Icon name="heart" style={styles.rightBtnIcon} />
44+
</Button>
45+
<Button
46+
small
47+
transparent
48+
title="view"
49+
onPress={() => this.props.onPress('share', rowID, rowData)}
50+
style={styles.rightBtn}
51+
>
52+
<Icon name="share" style={styles.rightBtnIcon} />
53+
</Button>
54+
</View>
55+
</Right>
56+
</ListItem>
57+
)
58+
}
59+
}

Example/src/loadingSpinner/index.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React, { Component } from 'react'
2+
import { Dimensions, ActivityIndicator } from 'react-native'
3+
import { View, Text } from 'native-base'
4+
5+
const { width, height } = Dimensions.get('window')
6+
7+
export default class LoadingSpinner extends Component {
8+
static defaultProps = {
9+
width,
10+
height,
11+
spinnerColor: 'dimgray',
12+
textColor: 'dimgray',
13+
text: ''
14+
};
15+
16+
render() {
17+
return (
18+
<View style={{
19+
width: this.props.width, height: this.props.height, justifyContent: 'center', alignItems: 'center'
20+
}}
21+
>
22+
<ActivityIndicator color={this.props.spinnerColor} />
23+
<View style={{ height: 10 }} />
24+
<Text note style={{ color: this.props.textColor }}>{this.props.text}</Text>
25+
</View>
26+
)
27+
}
28+
}

0 commit comments

Comments
 (0)