从React Native,Flutter到小程序(六)list,grid

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 样式中指定了一些尺寸和间距,但具体数值应根据实际情况进行调整,以适应不同尺寸和密度的屏幕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值