如何在颤动中创建加载更多列表视图

Posted

技术标签:

【中文标题】如何在颤动中创建加载更多列表视图【英文标题】:How to create load more listview in flutter 【发布时间】:2022-01-18 17:44:11 【问题描述】:

我想在列表视图中创建加载更多滚动视图。我的应用程序流程将 youtube 链接存储在 csv 文件中,并从我的应用程序中获取此链接并显示在我的列表视图中。但问题是我不想在应用程序打开时等待太多的加载时间。如果我的 csv 中有很多 youtube 链接。我会花费很多时间。所以,例如我只想显示 5视频处于初始状态,当加载更多时,在我的列表视图中显示更多 5 个视频。我该怎么做。我的代码如下。

import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
import 'videolist.dart';
import './models/models.dart';
import 'package:csv/csv.dart' as csv;
import 'package:http/http.dart' as http;

class DisplayVideo extends StatefulWidget 
  String id;
  @override
  DisplayVideo(this.id);
  _DisplayVideoState createState() => _DisplayVideoState();


class _DisplayVideoState extends State<DisplayVideo> 
  late YoutubePlayerController _controller ;
  Future<List<YoutubeDetail>> _loadCSV() async 
    Map<String, String> allData = 
      'login': '',
      'password': '',
    ;
    final Uri url = Uri.parse(
        'https://raw.githubusercontent.com/JornaldRem/bedtime_story/main/videoId.csv');
    final response = await http.get(url);
    csv.CsvToListConverter converter =
        new csv.CsvToListConverter(eol: '\r\n', fieldDelimiter: ',');
    List<List> listCreated = converter.convert(response.body);
    // the csv file is converted to a 2-Dimensional list
    List<YoutubeDetail> youtubeDetailList = [];
    for (int i = 0; i < listCreated.length; i++) 
      YoutubeDetail temp = YoutubeDetail(
        listCreated[i][0],
        listCreated[i][1],
      );

      youtubeDetailList.add(temp);
    
    return youtubeDetailList;
  

  @override
  void initState() 
    // TODO: implement initState
    super.initState();
    _controller = YoutubePlayerController(
      initialVideoId: widget.id,
      flags: YoutubePlayerFlags(
        autoPlay: true,
        mute: false,
      ),
    );
  
  @override
  Widget build(BuildContext context) 

    return Scaffold(
        appBar: AppBar(
          elevation: 0,
          title: Text('Title'),
          toolbarHeight: 60,
          backgroundColor: const Color(0xFF006666),
        ),
        body: Column(
          children: [
            Container(
              child: YoutubePlayer(
                controller: _controller,
                liveUIColor: Colors.amber,
              ),
            ),
            Expanded(
              child: Container(
                child: FutureBuilder(
                    future: _loadCSV(),
                    builder: (BuildContext context,
                        AsyncSnapshot<List<YoutubeDetail>> snapshot) 
                      if (snapshot.hasData) 
                        List<YoutubeDetail> videoDetail = snapshot.data!;
                        return ListView.builder(
                            shrinkWrap: true,
                            scrollDirection: Axis.vertical,
                            itemCount: videoDetail.length,
                            itemBuilder: (_, int index) 
                              if (index > 0) 
                                return GestureDetector(
                                  child: Container(
                                    height: 80,
                                    child: DisplayVideoView(
                                        videoDetail[index].url,
                                        videoDetail[index].title),
                                  ),
                                  onTap: ()
                                    String url = videoDetail[index].url;
                                    String id = url.substring(url.length - 11);
                                    print("HEllo");
                                    _controller.load(id);
                                    // DisplayVideo(id);
                                  
                                );
                               else 
                                return Container();
                              
                            );
                       else 
                        return Container();
                      
                    ),
              ),
            ),
          ],
        ));
  


class DisplayVideoView extends StatelessWidget 
  String videopath;
  String title;
  DisplayVideoView(this.videopath, this.title);
  @override
  Widget build(BuildContext context) 
    String url = videopath;
    String id = url.substring(url.length - 11);
    // TODO: implement build
    return Card(
      clipBehavior: Clip.antiAlias,
      child: Container(
        height: 150,
        padding: const EdgeInsets.all(0),
        child: Row(children: [
          Expanded(
            flex: 6,
            child: Container(
              decoration: BoxDecoration(
                  image: DecorationImage(
                      image: NetworkImage(
                          'https://img.youtube.com/vi/$id/mqdefault.jpg'),
                      fit: BoxFit.fill)),
            ),
          ),
          Spacer(
            flex: 1,
          ),
          Expanded(
            flex: 14,
            child: Container(
              padding: const EdgeInsets.only(top: 2),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(title,
                      style: TextStyle(
                          fontSize: 16.0, fontWeight: FontWeight.bold)),
                ],
              ),
            ),
          ),
        ]),
      ),
    );
  

【问题讨论】:

【参考方案1】:

您如何看待这种方法:

import 'package:flutter/material.dart';

class ExampleWidget extends StatefulWidget 
  const ExampleWidget(Key? key) : super(key: key);

  @override
  _ExampleWidgetState createState() => _ExampleWidgetState();


class _ExampleWidgetState extends State<ExampleWidget> 
  List<Widget> _myList = [];

  void _loadFiveMore() 
    _myList = <Widget>[
      ..._myList,
      for (int i = _myList.length; i < _myList.length + 5; i++)
        ListTile(title: Text('item $i')),
    ];
  

  @override
  void initState() 
    _loadFiveMore();
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        body: ListView(children: [
          ..._myList,
          OutlinedButton(
              onPressed: () 
                setState(() => _loadFiveMore());
              ,
              child: const Text('get 5 more'))
        ]),
      ),
    );
  


void main() 
  runApp(const ExampleWidget());

【讨论】:

以上是关于如何在颤动中创建加载更多列表视图的主要内容,如果未能解决你的问题,请参考以下文章

如何在列表视图的滚动中添加更多项目?

Android sqlite数据库-如何在滚动结束时显示列表视图添加 "加载更多项目"。

如何在数据来自 API 的颤动中创建下拉列表?

Swift,将更多数据加载到表视图中会导致滚动滞后

在 ListView 滚动结束时加载更多结果

NSManagedObject 如何重新加载