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

京东淘宝风格的商品视图

手机屏幕左右边缘紧靠图片左右边缘图片之间留间隙,这种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文件:


<?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

动画效果五

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


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

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

动画效果六

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


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


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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom