React Native
ScrollView
基于 React Native 的 ScrollView 组件实现类似 Flutter 中 ListView 功能的源代码示例:
import React from 'react';
import { ScrollView, Text } from 'react-native';
export default function ExampleListView() {
const data = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Bob' },
{ id: 4, name: 'Mary' },
{ id: 5, name: 'Peter' },
{ id: 6, name: 'Tom' },
{ id: 7, name: 'Linda' },
{ id: 8, name: 'Paul' }
];
return (
<ScrollView>
{data.map(item => (
<Text key={item.id}>{item.name}</Text>
))}
</ScrollView>
);
}
请注意,这只是一个简单的示例,您可以根据实际需求自定义样式和配置。如果需要更高级别的功能,建议选择 FlatList 或 SectionList 组件,它们提供了更丰富和灵活的数据渲染和列表显示方式。
FlatList
FlatList组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同。
FlatList更适于长列表数据,且元素个数可以增删。和ScrollView不同的是,FlatList并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。
FlatList组件必须的两个属性是data和renderItem。data是列表的数据源,而renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。
下面的例子创建了一个简单的FlatList,并预设了一些模拟数据。首先是初始化FlatList所需的data,其中的每一项(行)数据之后都在renderItem中被渲染成了Text组件,最后构成整个FlatList。
import React from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
});
const FlatListBasics = () => {
return (
<View style={styles.container}>
<FlatList
data={[
{key: 'Devin'},
{key: 'Dan'},
{key: 'Dominic'},
{key: 'Jackson'},
{key: 'James'},
{key: 'Joel'},
{key: 'John'},
{key: 'Jillian'},
{key: 'Jimmy'},
{key: 'Julie'},
]}
renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
/>
</View>
);
}
export default FlatListBasics;
SectionList
如果要渲染的是一组需要分组的数据,也许还带有分组标签的,那么SectionList将是个不错的选择
import React from 'react';
import { SectionList, StyleSheet, Text, View } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
sectionHeader: {
paddingTop: 2,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 2,
fontSize: 14,
fontWeight: 'bold',
backgroundColor: 'rgba(247,247,247,1.0)',
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
})
const SectionListBasics = () => {
return (
<View style={styles.container}>
<SectionList
sections={[
{title: 'D', data: ['Devin', 'Dan', 'Dominic']},
{title: 'J', data: ['Jackson', 'James', 'Jillian', 'Jimmy', 'Joel', 'John', 'Julie']},
]}
renderItem={({item}) => <Text style={styles.item}>{item}</Text>}
renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
keyExtractor={(item, index) => index}
/>
</View>
);
}
export default SectionListBasics;
Grid
使用 react-native-grid-component 的示例代码:
import React from 'react';
import { View, Image } from 'react-native';
import Grid from 'react-native-grid-component';
const data = [
{ id: 1, image: require('./images/1.jpg') },
{ id: 2, image: require('./images/2.jpg') },
{ id: 3, image: require('./images/3.jpg') },
{ id: 4, image: require('./images/4.jpg') },
{ id: 5, image: require('./images/5.jpg') },
{ id: 6, image: require('./images/6.jpg') },
{ id: 7, image: require('./images/7.jpg') },
{ id: 8, image: require('./images/8.jpg') },
];
export default function ExampleGrid() {
return (
<Grid
data={data}
renderItem={({ item }) => (
<View style={{ padding: 5 }}>
<Image source={item.image} />
</View>
)}
keyExtractor={item => item.id.toString()}
numColumns={3} // 设置每行显示 3 列
/>
);
}
在这个示例中,我们导入了 react-native-grid-component 并使用它来实现网格列表的功能。传递给 组件的各个属性与 FlatList 和 SectionList 类似,并增加了 numColumns 属性来控制列数。同时,在 renderItem 中也对每个项目进行了定制化呈现。
组合
用 React Native 中的 ScrollView 组件来实现一个滑动的视图,并在其中放置多个子元素,包括标题视图、列表视图和网格视图等子组件。下面是一份示例代码:
javascript
import React from 'react';
import { View, Text, FlatList, Image } from 'react-native';
const data = [
{id: '1', text: 'Item 1'},
{id: '2', text: 'Item 2'},
{id: '3', text: 'Item 3'},
{id: '4', text: 'Item 4'}
];
const images = [
{id: '1', uri: 'https://picsum.photos/200/300'},
{id: '2', uri: 'https://picsum.photos/200/300?random=1'},
{id: '3', uri: 'https://picsum.photos/200/300?random=2'},
{id: '4', uri: 'https://picsum.photos/200/300?random=3'},
{id: '5', uri: 'https://picsum.photos/200/300?random=4'},
{id: '6', uri: 'https://picsum.photos/200/300?random=5'},
{id: '7', uri: 'https://picsum.photos/200/300?random=6'},
{id: '8', uri: 'https://picsum.photos/200/300?random=7'}
];
export default function ExampleScrollView() {
return (
<View>
{/* 标题视图 */}
<Text style={{fontSize: 26, fontWeight: 'bold', marginVertical: 10}}>Title</Text>
{/* 列表视图 */}
<FlatList
data={data}
keyExtractor={item => item.id}
renderItem={({item}) => (
<View style={{padding: 10}}>
<Text>{item.text}</Text>
</View>
)}
/>
{/* 网格视图 */}
<FlatList
data={images}
numColumns={2}
keyExtractor={item => item.id}
renderItem={({item}) => (
<View style={{flex: 1, margin: 5}}>
<Image source={{uri: item.uri}} style={{width: '100%', height: 150}} />
</View>
)}
/>
</View>
);
}
在这个示例中,我们使用了 ScrollView 组件来承载多个子元素,并将标题视图、列表视图和网格视图等组件放置在 ScrollView 中。其中列表视图使用了 FlatList 组件,通过传递不同的数据源和渲染函数来展示不同的数据项;网格视图也是基于 FlatList 实现,通过 numColumns 属性控制展示列数。还可以根据自己的需要增加更多子组件,例如头部图片、底部按钮等。
Flutter
列表和网格1
在Flutter中,可以使用ListView组件来实现一个可以滑动的视图。这个视图可以包含许多子视图,包括标题视图,列表视图和网格视图等。
下面是一份示例代码:
import 'package:flutter/material.dart';
class MyPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: <Widget>[
// 标题视图
Container(
height: 60,
alignment: Alignment.center,
color: Colors.grey[200],
child: Text('My Title', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
),
// 列表视图
Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.5), spreadRadius: 1, blurRadius: 2)]
),
child: Column(
children: <Widget>[
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
ListTile(title: Text('Item 4')),
ListTile(title: Text('Item 5')),
],
),
),
// 网格视图
GridView.count(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
crossAxisCount: 2,
padding: EdgeInsets.all(10),
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: <Widget>[
GridTile(
child: Image.asset('assets/image-1.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 1', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
GridTile(
child: Image.asset('assets/image-2.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 2', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
GridTile(
child: Image.asset('assets/image-3.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 3', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
GridTile(
child: Image.asset('assets/image-4.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 4', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
GridTile(
child: Image.asset('assets/image-5.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 5', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
],
),
],
),
);
}
}
在这个示例中,我们使用ListView组件承载了多个子元素,包括标题视图、列表视图和网格视图。
其中,列表视图使用了容器Container组件设置间距和装饰属性; 网格视图使用了GridView.count组件设置网格视图的行列(crossAxisCount)及每个单元格之间的空隙(mainAxisSpacing/crossAxisSpacing)。
列表和网格2
用Slivers来实现上面的滑动视图,具体实现方式可以参考以下代码:
import 'package:flutter/material.dart';
class MyPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
// 标题
SliverAppBar(
title: Text('My Title'),
floating: true,
pinned: true,
snap: false,
),
// 列表视图
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.5), spreadRadius: 1, blurRadius: 2)]
),
child: ListTile(title: Text('Item ${index + 1}')),
);
}, childCount: 5),
),
// 网格视图
SliverGrid.count(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: <Widget>[
Container(
padding: EdgeInsets.all(5),
child: GridTile(
child: Image.asset('assets/image-1.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 1', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
),
Container(
padding: EdgeInsets.all(5),
child: GridTile(
child: Image.asset('assets/image-2.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 2', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
),
Container(
padding: EdgeInsets.all(5),
child: GridTile(
child: Image.asset('assets/image-3.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 3', textAlign: TextAlign.center,style: TextStyle(fontSize: 16)),
),
),
),
Container(
padding: EdgeInsets.all(5),
child: GridTile(
child: Image.asset('assets/image-4.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 4', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
),
Container(
padding: EdgeInsets.all(5),
child: GridTile(
child: Image.asset('assets/image-5.jpg', fit: BoxFit.cover),
footer: Container(
color: Colors.white.withOpacity(0.8),
child: Text('Grid Item 5', textAlign: TextAlign.center, style: TextStyle(fontSize: 16)),
),
),
),
],
),
],
),
);
}
}
在这个示例中,我们使用了CustomScrollView组件来创建一个自定义的滑动视图。其中,Slivers被用来作为CustomScrollView的子部件。
在代码中,使用了SliverAppBar组件来创建标题栏,并将其固定在屏幕顶部进行漂浮;使用了SliverList组件来创建列表视图;使用了SliverGrid.count组件来创建网格视图。和之前的示例代码相比,我们移除了单独的Container和ListView组件,并用相关的Slivers替代它们。
通过调整Slivers中的参数,可以根据实际情况修改滑动视图的外观和行为方式。
微信小程序
列表和网格
index.wxml:
<scroll-view scroll-y="{{true}}" class="container">
<!-- 标题视图 -->
<view class="title">
<text>My Title</text>
</view>
<!-- 列表视图 -->
<view class="list">
<view wx:for="{{listData}}" wx:key="id">
<!-- 列表项内容 -->
<text>{{item.title}}</text>
</view>
</view>
<!-- 网格视图 -->
<view class="grid">
<view wx:for="{{gridData}}" wx:key="id" class="cell">
<image src="{{item.image}}" />
<text>{{item.title}}</text>
</view>
</view>
</scroll-view>
index.js:
Page({
data: {
listData: [
{ id: '1', title: 'Item 1' },
{ id: '2', title: 'Item 2' },
{ id: '3', title: 'Item 3' },
{ id: '4', title: 'Item 4' },
{ id: '5', title: 'Item 5' }
],
gridData: [
{ id: '1', image: '/images/image-1.jpg', title: 'Grid Item 1' },
{ id: '2', image: '/images/image-2.jpg', title: 'Grid Item 2' },
{ id: '3', image: '/images/image-3.jpg', title: 'Grid Item 3' },
{ id: '4', image: '/images/image-4.jpg', title: 'Grid Item 4' },
{ id: '5', image: '/images/image-5.jpg', title: 'Grid Item 5' },
{ id: '6', image: '/images/image-6.jpg', title: 'Grid Item 6' },
{ id: '7', image: '/images/image-7.jpg', title: 'Grid Item 7' }
]
}
})
index.wxss:
.container {
height: 100%;
padding: 10px;
}
.title {
height: 50px;
line-height: 50px;
text-align: center;
background-color: #eeeeee;
font-size: 24px;
font-weight: bold;
}
.list {
margin-top: 10px;
padding: 10px;
background-color: #ffffff;
border-radius: 5px;
}
.grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
margin-top: 10px;
padding: 10px;
background-color: #ffffff;
border-radius: 5px;
}
.cell {
width: 48%;
margin-bottom: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
border-radius: 5px;
overflow: hidden;
}
.cell image {
width: 100%;
height: 0;
padding-bottom: 100%;
}
在这个示例中,我们使用 scroll-view 组件承载了多个子元素,包括标题视图、列表视图和网格视图等组件。其中,列表视图使用了 wx:for 循环渲染数据源中的每一个元素;网格视图则是基于纯 CSS 实现的,通过 display: flex 和 flex-wrap: wrap 以及各种样式规则来控制网格布局。还可以根据自己的需要增加更多子组件,例如头部图片、底部按钮等。
注意,这里我们在 CSS 样式中指定了一些尺寸和间距,但具体数值应根据实际情况进行调整,以适应不同尺寸和密度的屏幕。