📜  Flutter – 实现下拉刷新

📅  最后修改于: 2021-09-23 06:22:49             🧑  作者: Mango

下拉刷新或(滑动刷新)功能使用户能够下拉以获取更多数据。在许多现代应用程序中都可以看到下拉刷新功能。可以在可滚动的组件中实现下拉刷新功能。

在本文中,我们将在Flutter实现此功能。如果您不熟悉flutter,请在深入阅读本文之前访问flutter.dev。 Flutter是关于小部件的, flutter的一切都只是小部件。 Flutter还提供了一个小部件来实现此功能以及即RefreshIndicator。

RefreshIndicator:当孩子的Scrollable后代overscrolls 时,动画圆形进度指示器淡入视图。当滚动结束时,如果指标已被拖到足够远使其变得完全不透明,则调用onRefresh回调。回调预计会更新可滚动的内容,然后完成它返回的 Future。回调的 Future 完成后刷新指示器消失。

要创建flutter应用程序,请打开终端/命令并运行以下命令:

flutter create app_name
// app_name should be the name of your app

Example:
flutter create demo_app

运行此命令后,您应该有一个指定app_name的文件夹。导航到该文件夹并打开lib/main。dart文件。

Note: In order to implement pull-to-refresh feature we are not going to use any other dependencies.

要创建 RefreshIndicator,请使用以下语法:

RefreshIndicator(
  child: ...
  onRefresh: ...
)

These are required fields.
child: Should be a scrollable widget
onRefresh: A function that should return a future. 
       Future is a type in dart.

我们将逐步实现这一点。

第 1 步:如上所述,为了使 RefreshIndicator 正常工作,我们将需要一个可滚动组件。为此,我们将使用 ListView。在这一步中,我们将为我们的应用程序定义一些演示数据。

Dart
// Local State to display items in listview
List _demoData;
 
// This method will run once widget is loaded
// i.e when widget is mounting
@override
void initState() {
  // initializing state / demo data
  _demoData = [
    "Flutter",
    "React Native",
    "Cordova/ PhoneGap",
    "Native Script"
  ];
  super.initState();
}


Dart
... some code
 
ListView.builder(
  itemBuilder: (ctx, idx) {
    // List Item
    return Card(
      child: ListTile(
        title: Text(_demoData[idx]),
      ),
    );
  },
 
  // Length of the list
  itemCount: _demoData.length,
 
  // To make listView scrollable
  // even if there is only a single item.
  physics: const AlwaysScrollableScrollPhysics(),
)
   
... some code


Dart
... some code
 
RefreshIndicator(
  child: ListView.builder(
    itemBuilder: (ctx, idx) {
      // List Item
      return Card(
        child: ListTile(
          title: Text(_demoData[idx]),
        ),
      );
    },
 
    // Length of the list
    itemCount: _demoData.length,
 
    // To make listView scrollable
    // even if there is only a single item.
    physics: const AlwaysScrollableScrollPhysics(),
  ),
  // Function that will be called when
  // user pulls the ListView downward
  onRefresh: () {
    return Future.delayed(
      Duration(seconds: 1),
      () {
        /// adding elements in list after [1 seconds] delay
        /// to mimic network call
        ///
        /// Remember: setState is necessary so that
        /// build method will run again otherwise
        /// list will not show all elements
        setState(() {
          _demoData.addAll(["Ionic", "Xamarin"]);
        });
         
        // showing snackbar
        _scaffoldKey.currentState.showSnackBar(
          SnackBar(
            content: const Text('Page Refreshed'),
          ),
        );
      },
    );
  },
)
   
... some code


Dart
import 'package:flutter/material.dart';
 
void main() => runApp(MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GeeksforGeeks',
 
      // to hide debug banner
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: HomePage(),
    );
  }
}
 
/// [StatefulWidget] so that we can change
/// internal state to show proper working
/// of [PULL TO REFRESH] feature
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
 
class _HomePageState extends State {
  // ScaffoldKey object. This is required
  // to show snackbar
  // This is optional. This is not required always
  GlobalKey _scaffoldKey;
 
  // Local State to display items in listview
  List _demoData;
 
  // This method will run once widget is loaded
  // i.e when widget is mounting
  @override
  void initState() {
    // initializing states
    _demoData = [
      "Flutter",
      "React Native",
      "Cordova/ PhoneGap",
      "Native Script"
    ];
    _scaffoldKey = GlobalKey();
    super.initState();
  }
 
  // This method will run when widget is unmounting
  @override
  void dispose() {
    // disposing states
    _scaffoldKey?.currentState?.dispose();
    super.dispose();
  }
 
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: const Text('GeeksforGeeks'),
        ),
        // Widget to show RefreshIndicator
        body: RefreshIndicator(
          child: ListView.builder(
            itemBuilder: (ctx, idx) {
              // List Item
              return Card(
                child: ListTile(
                  title: Text(_demoData[idx]),
                ),
              );
            },
 
            // Length of the list
            itemCount: _demoData.length,
 
            // To make listView scrollable
            // even if there is only a single item.
            physics: const AlwaysScrollableScrollPhysics(),
          ),
          // Function that will be called when
          // user pulls the ListView downward
          onRefresh: () {
            return Future.delayed(
              Duration(seconds: 1),
              () {
                /// adding elements in list after [1 seconds] delay
                /// to mimic network call
                ///
                /// Remember: [setState] is necessary so that
                /// build method will run again otherwise
                /// list will not show all elements
                setState(() {
                  _demoData.addAll(["Ionic", "Xamarin"]);
                });
 
                // showing snackbar
                _scaffoldKey.currentState.showSnackBar(
                  SnackBar(
                    content: const Text('Page Refreshed'),
                  ),
                );
              },
            );
          },
        ),
      ),
    );
  }
}


第 2 步:我们将使用 ListItem 和 AlwaysScrollingPhysics 创建我们的 ListView。

Dart

... some code
 
ListView.builder(
  itemBuilder: (ctx, idx) {
    // List Item
    return Card(
      child: ListTile(
        title: Text(_demoData[idx]),
      ),
    );
  },
 
  // Length of the list
  itemCount: _demoData.length,
 
  // To make listView scrollable
  // even if there is only a single item.
  physics: const AlwaysScrollableScrollPhysics(),
)
   
... some code

第 3 步:最后将 ListView 包装到 RefreshIndicator 中以使用下拉刷新功能。

Dart

... some code
 
RefreshIndicator(
  child: ListView.builder(
    itemBuilder: (ctx, idx) {
      // List Item
      return Card(
        child: ListTile(
          title: Text(_demoData[idx]),
        ),
      );
    },
 
    // Length of the list
    itemCount: _demoData.length,
 
    // To make listView scrollable
    // even if there is only a single item.
    physics: const AlwaysScrollableScrollPhysics(),
  ),
  // Function that will be called when
  // user pulls the ListView downward
  onRefresh: () {
    return Future.delayed(
      Duration(seconds: 1),
      () {
        /// adding elements in list after [1 seconds] delay
        /// to mimic network call
        ///
        /// Remember: setState is necessary so that
        /// build method will run again otherwise
        /// list will not show all elements
        setState(() {
          _demoData.addAll(["Ionic", "Xamarin"]);
        });
         
        // showing snackbar
        _scaffoldKey.currentState.showSnackBar(
          SnackBar(
            content: const Text('Page Refreshed'),
          ),
        );
      },
    );
  },
)
   
... some code

完整的源代码:

Dart

import 'package:flutter/material.dart';
 
void main() => runApp(MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GeeksforGeeks',
 
      // to hide debug banner
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: HomePage(),
    );
  }
}
 
/// [StatefulWidget] so that we can change
/// internal state to show proper working
/// of [PULL TO REFRESH] feature
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
 
class _HomePageState extends State {
  // ScaffoldKey object. This is required
  // to show snackbar
  // This is optional. This is not required always
  GlobalKey _scaffoldKey;
 
  // Local State to display items in listview
  List _demoData;
 
  // This method will run once widget is loaded
  // i.e when widget is mounting
  @override
  void initState() {
    // initializing states
    _demoData = [
      "Flutter",
      "React Native",
      "Cordova/ PhoneGap",
      "Native Script"
    ];
    _scaffoldKey = GlobalKey();
    super.initState();
  }
 
  // This method will run when widget is unmounting
  @override
  void dispose() {
    // disposing states
    _scaffoldKey?.currentState?.dispose();
    super.dispose();
  }
 
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: const Text('GeeksforGeeks'),
        ),
        // Widget to show RefreshIndicator
        body: RefreshIndicator(
          child: ListView.builder(
            itemBuilder: (ctx, idx) {
              // List Item
              return Card(
                child: ListTile(
                  title: Text(_demoData[idx]),
                ),
              );
            },
 
            // Length of the list
            itemCount: _demoData.length,
 
            // To make listView scrollable
            // even if there is only a single item.
            physics: const AlwaysScrollableScrollPhysics(),
          ),
          // Function that will be called when
          // user pulls the ListView downward
          onRefresh: () {
            return Future.delayed(
              Duration(seconds: 1),
              () {
                /// adding elements in list after [1 seconds] delay
                /// to mimic network call
                ///
                /// Remember: [setState] is necessary so that
                /// build method will run again otherwise
                /// list will not show all elements
                setState(() {
                  _demoData.addAll(["Ionic", "Xamarin"]);
                });
 
                // showing snackbar
                _scaffoldKey.currentState.showSnackBar(
                  SnackBar(
                    content: const Text('Page Refreshed'),
                  ),
                );
              },
            );
          },
        ),
      ),
    );
  }
}
Note: In some cases, you will notice that the refresh indicator is not showing.
      To make it visible all the time please use physics: In Flutter all the scrollable
      widgets have physics properties.

即使列表中只有几个元素,以下内容也将启用滚动。

ListView(
  physics: const AlwaysScrollableScrollPhysics(),
  ...
)

输出

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!