欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

How to animate the list items when list is loaded in react native

程序员文章站 2022-06-01 11:13:47
...

京东淘宝风格的商品视图

手机屏幕左右边缘紧靠图片左右边缘图片之间留间隙,这种style的渲染技巧互联网上你可能很难搜到

列表项动画基于以下基础代码实现:

src/ListItem.js文件完整的代码如下:

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文件:

How to animate the list items when list is loaded in react native

<?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"
    }
  }, {
    "name": {
      "title": "mr",
      "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"
    }
  }, {
    "name": {
      "title": "miss",
      "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"
    }
  }, {
    "name": {
      "title": "miss",
      "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"
    }
  }, {
    "name": {
      "title": "miss",
      "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"
  }
}

在安卓和苹果手机模拟器中运行的效果截图如下:

How to animate the list items when list is loaded in react native

How to animate the list items when list is loaded in react native

真正实现列表图片动画效果的步骤就从这儿开始吧


动画效果一

我们需要在以上项目中只需要修改ListItem.js代码文件,下图中标记的部分为新增加的代码行,截图如下:

How to animate the list items when list is loaded in react native

动画效果视频地址:https://pan.baidu.com/s/1I1bSxqkDsDYCIgFw8mqv5Q

动画效果二

注意App.js文件中标记的部分为新增加的代码行,截图如下:

How to animate the list items when list is loaded in react native

注意ListItem.js文件中标记的部分为新增加的代码行,截图如下:

How to animate the list items when list is loaded in react native

动画效果视频地址:https://pan.baidu.com/s/1-uuuf0S_3i67WgGaDWWmzg

动画效果三

只需要修改ListItem.js代码文件,下图中标记的部分为修改后的代码块,截图如下:

How to animate the list items when list is loaded in react native

动画效果视频地址:https://pan.baidu.com/s/1bdCL_oYq0xjHdwpHrG7Rpg

动画效果四

只需要修改ListItem.js代码文件,下图中标记的部分为修改后的代码块,截图如下:

How to animate the list items when list is loaded in react native

动画效果视频地址:https://pan.baidu.com/s/1JZNHKm7OcNpP2rt9cIUX8A

动画效果五

注意App.js文件中标记的部分为新增加的代码,截图如下:

How to animate the list items when list is loaded in react native

注意ListItem.js文件中标记的部分为修改后的代码,截图如下:

How to animate the list items when list is loaded in react native

动画效果视频地址:https://pan.baidu.com/s/1toHEv5qM2OdDtckmb8zu9Q

动画效果六

注意App.js文件中标记的部分为新增加的代码,截图如下

How to animate the list items when list is loaded in react native

注意ListItem.js文件中标记的部分为修改后的代码,截图如下:

How to animate the list items when list is loaded in react native

动画效果视频地址:https://pan.baidu.com/s/1AyooWPWXQGj2ZHCuuxWf3g