京东淘宝风格的商品视图
手机屏幕左右边缘紧靠图片左右边缘图片之间留间隙,这种style的渲染技巧互联网上你可能很难搜到
列表项动画基于以下基础代码实现:
import React,{Component} from 'React'; import { TouchableWithoutFeedback,Image,Animated,} from 'react-native'; export default class ListItem extends Component { state = { animatePress: new Animated.Value(1),} animateIn() { Animated.timing(this.state.animatePress,{ toValue: 0.8,duration: 200 }).start() } animateOut() { Animated.timing(this.state.animatePress,{ toValue: 1,duration: 200 }).start() } render() { const { itemWidth,image,onPressItem } = this.props return ( <TouchableWithoutFeedback onPress = {() => onPressItem && onPressItem(this.props.image)} onPressIn = {() => this.animateIn()} onPressOut = {() => this.animateOut()} > <Animated.View style = {{ marginTop: 2,marginBottom: 2,paddingRight: 4,transform: [ { scale: this.state.animatePress },] }}> <Image style={{ width: itemWidth,height: 200 }} source={image} /> </Animated.View> </TouchableWithoutFeedback> ); } }App.js文件完整的代码如下:
import React,{Component} from 'React'; import { StyleSheet,FlatList,View,Button,Dimensions } from 'react-native'; import ListItem from './src/ListItem'; const ITEM_WIDTH = Dimensions.get('window').width; export default class App extends Component { state = { columns: 1,key: 1,array: [],} constructor(props) { super(props) this.getImageData = this.getImageData.bind(this) } componentWillMount() { this.getImageData() } getImageData() { fetch('https://randomuser.me/api?page=1&results=10&inc=picture,name',{ method: 'GET',headers: { 'Accept': 'application/json','Content-Type': 'application/json',},}) .then((response) => response.json()) .then((responseJson) => { let newArray = this.state.array.slice() let concatArray = newArray.concat(responseJson.results) this.setState({ array: concatArray }) }) } render() { const { columns,key,array } = this.state return ( <View style={{flex:1}}> <Button onPress = {() => { let { columns,key } = this.state columns = columns === 3 ? 1 : 3 this.setState({ columns: columns,key: key + 1 }) }} title = 'Toggle Layout' /> <View style = {styles.container}> <FlatList key = {key} numColumns = {columns} data = {array} renderItem = {({ item,index }) => { return <ListItem itemWidth = {ITEM_WIDTH / columns - 2 } image = {{ uri: item.picture.large }} /> }} keyExtractor = { (item,index) => { return `${item.name.first + index}` } } /> </View> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1,backgroundColor: '#f5fcff',justifyContent: 'space-around',flexDirection:'row',} })
支持苹果手机的https协议链接请求,我们需要配置info.plist文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleDisplayName</key> <string>jason</string> <key>CFBundleExecutable</key> <string>$(EXECUTABLE_NAME)</string> <key>CFBundleIdentifier</key> <string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>$(PRODUCT_NAME)</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>1</string> <key>LSRequiresIPhoneOS</key> <true/> <key>UILaunchStoryboardName</key> <string>LaunchScreen</string> <key>UIrequiredDeviceCapabilities</key> <array> <string>armv7</string> </array> <key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> <key>UIViewControllerBasedStatusBarAppearance</key> <false/> <key>NSLocationWhenInUseUsageDescription</key> <string></string> <key>NSAppTransportSecurity</key> <!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ --> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSExceptionDomains</key> <dict> <key>localhost</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> <key>NSIncludesSubdomains</key> <true/> </dict> </dict> </dict> </dict> </plist>
本范例使用的链
https://randomuser.me/api?page=1&results=10&inc=picture,name接返回的数据如下:
{ "results": [{ "name": { "title": "mr","first": "eric","last": "price" },"picture": { "large": "https://randomuser.me/api/portraits/men/40.jpg","medium": "https://randomuser.me/api/portraits/med/men/40.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/men/40.jpg" } },{ "name": { "title": "ms","first": "sheryl","last": "long" },"picture": { "large": "https://randomuser.me/api/portraits/women/57.jpg","medium": "https://randomuser.me/api/portraits/med/women/57.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/women/57.jpg" } },{ "name": { "title": "mr","first": "everett","last": "perry" },"picture": { "large": "https://randomuser.me/api/portraits/men/49.jpg","medium": "https://randomuser.me/api/portraits/med/men/49.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/men/49.jpg" } },{ "name": { "title": "miss","first": "nella","last": "palo" },"picture": { "large": "https://randomuser.me/api/portraits/women/49.jpg","medium": "https://randomuser.me/api/portraits/med/women/49.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/women/49.jpg" } },"first": "maxime","last": "jones" },"picture": { "large": "https://randomuser.me/api/portraits/men/79.jpg","medium": "https://randomuser.me/api/portraits/med/men/79.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/men/79.jpg" } },"first": "audrey","last": "webb" },"picture": { "large": "https://randomuser.me/api/portraits/women/24.jpg","medium": "https://randomuser.me/api/portraits/med/women/24.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/women/24.jpg" } },{ "name": { "title": "monsieur","first": "soren","last": "lambert" },"picture": { "large": "https://randomuser.me/api/portraits/men/98.jpg","medium": "https://randomuser.me/api/portraits/med/men/98.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/men/98.jpg" } },"first": "clara","last": "nieto" },"picture": { "large": "https://randomuser.me/api/portraits/women/31.jpg","medium": "https://randomuser.me/api/portraits/med/women/31.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/women/31.jpg" } },"first": "kübra","last": "düşenkalkar" },"picture": { "large": "https://randomuser.me/api/portraits/women/80.jpg","medium": "https://randomuser.me/api/portraits/med/women/80.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/women/80.jpg" } },{ "name": { "title": "mrs","first": "michelle","last": "garza" },"picture": { "large": "https://randomuser.me/api/portraits/women/39.jpg","medium": "https://randomuser.me/api/portraits/med/women/39.jpg","thumbnail": "https://randomuser.me/api/portraits/thumb/women/39.jpg" } }],"info": { "seed": "9639f987ad3e2210","results": 10,"page": 1,"version": "1.1" } }
在安卓和苹果手机模拟器中运行的效果截图如下:
动画效果一
我们需要在以上项目中只需要修改ListItem.js代码文件,下图中标记的部分为新增加的代码行,截图如下:
动画效果视频地址:https://pan.baidu.com/s/1I1bSxqkDsDYCIgFw8mqv5Q
动画效果二
注意App.js文件中标记的部分为新增加的代码行,截图如下:
注意ListItem.js文件中标记的部分为新增加的代码行,截图如下:
动画效果视频地址:https://pan.baidu.com/s/1-uuuf0S_3i67WgGaDWWmzg
动画效果三
只需要修改ListItem.js代码文件,下图中标记的部分为修改后的代码块,截图如下:
动画效果视频地址:https://pan.baidu.com/s/1bdCL_oYq0xjHdwpHrG7Rpg
动画效果四
只需要修改ListItem.js代码文件,下图中标记的部分为修改后的代码块,截图如下:
动画效果视频地址:https://pan.baidu.com/s/1JZNHKm7OcNpP2rt9cIUX8A
动画效果五
注意ListItem.js文件中标记的部分为修改后的代码,截图如下:
动画效果视频地址:https://pan.baidu.com/s/1toHEv5qM2OdDtckmb8zu9Q
动画效果六
注意ListItem.js文件中标记的部分为修改后的代码,截图如下: