亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Flutter實現(xiàn)下拉刷新和上拉加載更多

 更新時間:2022年08月24日 09:59:35   作者:曉果博客  
這篇文章主要為大家詳細介紹了Flutter實現(xiàn)下拉刷新和上拉加載更多,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Flutter實現(xiàn)下拉刷新和上拉加載更多的具體代碼,供大家參考,具體內(nèi)容如下

效果

下拉刷新

如果實現(xiàn)下拉刷新,必須借助RefreshIndicator,在listview外面包裹一層RefreshIndicator,然后在RefreshIndicator里面實現(xiàn)onRefresh方法。

body: movieList.length == 0
? ? ? ? ? ? new Center(child: new CircularProgressIndicator())
? ? ? ? ? : new RefreshIndicator(
? ? ? ? ? ? ? color: const Color(0xFF4483f6),
? ? ? ? ? ? ? //下拉刷新
? ? ? ? ? ? ? child: ListView.builder(
? ? ? ? ? ? ? ? itemCount: movieList.length + 1,
? ? ? ? ? ? ? ? itemBuilder: (context, index) {
? ? ? ? ? ? ? ? ? if (index == movieList.length) {
? ? ? ? ? ? ? ? ? ? return _buildProgressMoreIndicator();
? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? return renderRow(index, context);
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? controller: _controller, //指明控制器加載更多使用
? ? ? ? ? ? ? ),
? ? ? ? ? ? ? onRefresh: _pullToRefresh,
? ? ? ? ? ? ),

onRefresh方法的實現(xiàn)_pullToRefresh,注意這里必須使用async 不然報錯

?/**
? ?* 下拉刷新,必須異步async不然會報錯
? ?*/
? Future _pullToRefresh() async {
? ? currentPage = 0;
? ? movieList.clear();
? ? loadMoreData();
? ? return null;
? }

異步加載數(shù)據(jù),注意:在Flutter中刷新數(shù)據(jù)使用的是setState,不然無效,數(shù)據(jù)不會刷新;數(shù)據(jù)的獲取需要使用[]取值,不能使用對象“ . ”的取值方法!

//加載列表數(shù)據(jù)
loadMoreData() async {
? ? this.currentPage++;
? ? var start = (currentPage - 1) * pageSize;
? ? var url =
? ? ? ? "https://api.douban.com/v2/movie/$movieType?start=$start&count=$pageSize";
? ? Dio dio = new Dio();
? ? Response response = await dio.get(url);
? ? setState(() {
? ? ? movieList.addAll(response.data["subjects"]);
? ? ? totalSize = response.data["total"];
? ? });
? }

上拉加載更多

加載更多需要對ListView進行監(jiān)聽,所以需要進行監(jiān)聽器的設(shè)置,在State中進行監(jiān)聽器的初始化。

//初始化滾動監(jiān)聽器,加載更多使用
? ScrollController _controller = new ScrollController();

在構(gòu)造器中設(shè)置監(jiān)聽

?//固定寫法,初始化滾動監(jiān)聽器,加載更多使用
? ? _controller.addListener(() {
? ? ? var maxScroll = _controller.position.maxScrollExtent;
? ? ? var pixel = _controller.position.pixels;
? ? ? if (maxScroll == pixel && movieList.length < totalSize) {
? ? ? ? setState(() {
? ? ? ? ? loadMoreText = "正在加載中...";
? ? ? ? ? loadMoreTextStyle =
? ? ? ? ? ? ? new TextStyle(color: const Color(0xFF4483f6), fontSize: 14.0);
? ? ? ? });
? ? ? ? loadMoreData();
? ? ? } else {
? ? ? ? setState(() {
? ? ? ? ? loadMoreText = "沒有更多數(shù)據(jù)";
? ? ? ? ? loadMoreTextStyle =
? ? ? ? ? ? ? new TextStyle(color: const Color(0xFF999999), fontSize: 14.0);
? ? ? ? });
? ? ? }
? ? });

在listView中添加監(jiān)聽controller方法

自此,F(xiàn)lutter如何實現(xiàn)下拉刷新和上拉加載更多完成…

整個列表頁面代碼參考如下:

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:douban/pages/movie/movieDetail.dart';

class MovieList extends StatefulWidget {
? String movieType;
? //構(gòu)造器傳遞數(shù)據(jù)(并且接收上個頁面?zhèn)鬟f的數(shù)據(jù))
? MovieList({Key key, this.movieType}) : super(key: key);
? @override
? State<StatefulWidget> createState() {
? ? // TODO: implement createState
? ? return new MovieListState(movieType: this.movieType);
? }
}

class MovieListState extends State<MovieList> {
? String movieType;
? String typeName;
? List movieList = new List();
? int currentPage = 0; //第一頁
? int pageSize = 10; //頁容量
? int totalSize = 0; //總條數(shù)
? String loadMoreText = "沒有更多數(shù)據(jù)";
? TextStyle loadMoreTextStyle =
? ? ? new TextStyle(color: const Color(0xFF999999), fontSize: 14.0);
? TextStyle titleStyle =
? ? ? new TextStyle(color: const Color(0xFF757575), fontSize: 14.0);
? //初始化滾動監(jiān)聽器,加載更多使用
? ScrollController _controller = new ScrollController();

? /**
? ?* 構(gòu)造器接收(MovieList)數(shù)據(jù)
? ?*/
? MovieListState({Key key, this.movieType}) {
? ? //固定寫法,初始化滾動監(jiān)聽器,加載更多使用
? ? _controller.addListener(() {
? ? ? var maxScroll = _controller.position.maxScrollExtent;
? ? ? var pixel = _controller.position.pixels;
? ? ? if (maxScroll == pixel && movieList.length < totalSize) {
? ? ? ? setState(() {
? ? ? ? ? loadMoreText = "正在加載中...";
? ? ? ? ? loadMoreTextStyle =
? ? ? ? ? ? ? new TextStyle(color: const Color(0xFF4483f6), fontSize: 14.0);
? ? ? ? });
? ? ? ? loadMoreData();
? ? ? } else {
? ? ? ? setState(() {
? ? ? ? ? loadMoreText = "沒有更多數(shù)據(jù)";
? ? ? ? ? loadMoreTextStyle =
? ? ? ? ? ? ? new TextStyle(color: const Color(0xFF999999), fontSize: 14.0);
? ? ? ? });
? ? ? }
? ? });
? }

? //加載列表數(shù)據(jù)
? loadMoreData() async {
? ? this.currentPage++;
? ? var start = (currentPage - 1) * pageSize;
? ? var url =
? ? ? ? "https://api.douban.com/v2/movie/$movieType?start=$start&count=$pageSize";
? ? Dio dio = new Dio();
? ? Response response = await dio.get(url);
? ? setState(() {
? ? ? movieList.addAll(response.data["subjects"]);
? ? ? totalSize = response.data["total"];
? ? });
? }

? @override
? void initState() {
? ? super.initState();
? ? //設(shè)置當(dāng)前導(dǎo)航欄的標題
? ? switch (movieType) {
? ? ? case "in_theaters":
? ? ? ? typeName = "正在熱映";
? ? ? ? break;
? ? ? case "coming_soon":
? ? ? ? typeName = "即將上映";
? ? ? ? break;
? ? ? case "top250":
? ? ? ? typeName = "Top250";
? ? ? ? break;
? ? }

? ? //加載第一頁數(shù)據(jù)
? ? loadMoreData();
? }

? /**
? ?* 下拉刷新,必須異步async不然會報錯
? ?*/
? Future _pullToRefresh() async {
? ? currentPage = 0;
? ? movieList.clear();
? ? loadMoreData();
? ? return null;
? }

? @override
? Widget build(BuildContext context) {
? ? // TODO: implement build
? ? return new Scaffold(
? ? ? backgroundColor: Colors.white,
? ? ? appBar: new AppBar(
? ? ? ? leading: new IconButton(
? ? ? ? ? icon: const Icon(Icons.arrow_back),
? ? ? ? ? onPressed:null ,
? ? ? ? ),
? ? ? ? title: new Text(typeName != null ? typeName : "正在加載中...",
? ? ? ? ? ? style: new TextStyle(color: Colors.black)),
? ? ? ? backgroundColor: Colors.white,
? ? ? ),
? ? ? body: movieList.length == 0
? ? ? ? ? ? new Center(child: new CircularProgressIndicator())
? ? ? ? ? : new RefreshIndicator(
? ? ? ? ? ? ? color: const Color(0xFF4483f6),
? ? ? ? ? ? ? //下拉刷新
? ? ? ? ? ? ? child: ListView.builder(
? ? ? ? ? ? ? ? itemCount: movieList.length + 1,
? ? ? ? ? ? ? ? itemBuilder: (context, index) {
? ? ? ? ? ? ? ? ? if (index == movieList.length) {
? ? ? ? ? ? ? ? ? ? return _buildProgressMoreIndicator();
? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? return renderRow(index, context);
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? controller: _controller, //指明控制器加載更多使用
? ? ? ? ? ? ? ),
? ? ? ? ? ? ? onRefresh: _pullToRefresh,
? ? ? ? ? ? ),
? ? );
? }

? /**
? ?* 加載更多進度條
? ?*/
? Widget _buildProgressMoreIndicator() {
? ? return new Padding(
? ? ? padding: const EdgeInsets.all(15.0),
? ? ? child: new Center(
? ? ? ? child: new Text(loadMoreText, style: loadMoreTextStyle),
? ? ? ),
? ? );
? }

? /**
? ?* 列表的ltem
? ?*/
? renderRow(index, context) {
? ? var movie = movieList[index];
? ? var id = movie["id"];
? ? var title = movie["title"];
? ? var type = movie["genres"].join("、");
? ? var year = movie["year"];
? ? var score = movie["rating"]["average"];
? ? return new Container(
? ? ? ? height: 200,
? ? ? ? color: Colors.white,
? ? ? ? child: new InkWell(
? ? ? ? ? onTap: () {
? ? ? ? ? ? Navigator.of(context).push(new MaterialPageRoute(
? ? ? ? ? ? ? ? builder: (ctx) => new MovieDetail(movieId: id)));
? ? ? ? ? },
? ? ? ? ? child: new Column(
? ? ? ? ? ? children: <Widget>[
? ? ? ? ? ? ? new Container(
? ? ? ? ? ? ? ? height: 199,
? ? ? ? ? ? ? ? // color: Colors.blue,
? ? ? ? ? ? ? ? child: new Row(
? ? ? ? ? ? ? ? ? children: <Widget>[
? ? ? ? ? ? ? ? ? ? new Container(
? ? ? ? ? ? ? ? ? ? ? width: 120.0,
? ? ? ? ? ? ? ? ? ? ? height: 180.0,
? ? ? ? ? ? ? ? ? ? ? margin: const EdgeInsets.all(10.0),
? ? ? ? ? ? ? ? ? ? ? child: Image.network(movie["images"]["small"]),
? ? ? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? ? ? Expanded(
? ? ? ? ? ? ? ? ? ? ? child: new Container(
? ? ? ? ? ? ? ? ? ? ? ? height: 180.0,
? ? ? ? ? ? ? ? ? ? ? ? margin: const EdgeInsets.all(12.0),
? ? ? ? ? ? ? ? ? ? ? ? child: new Column(
? ? ? ? ? ? ? ? ? ? ? ? ? mainAxisAlignment: MainAxisAlignment.spaceBetween,
? ? ? ? ? ? ? ? ? ? ? ? ? crossAxisAlignment: CrossAxisAlignment.start,
? ? ? ? ? ? ? ? ? ? ? ? ? children: <Widget>[
? ? ? ? ? ? ? ? ? ? ? ? ? ? new Text(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "電影名稱:$title",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? style: titleStyle,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? overflow: TextOverflow.ellipsis,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? ? ? ? ? ? ? new Text(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "電影類型:$type",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? style: titleStyle,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? overflow: TextOverflow.ellipsis,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? ? ? ? ? ? ? new Text(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "上映年份:$year",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? style: titleStyle,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? overflow: TextOverflow.ellipsis,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? ? ? ? ? ? ? new Text(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "豆瓣評分:$score",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? style: titleStyle,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? overflow: TextOverflow.ellipsis,
? ? ? ? ? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? ? ? ? ? ? ],
? ? ? ? ? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? ? ],
? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ),
? ? ? ? ? ? ? //分割線
? ? ? ? ? ? ? new Divider(height: 1)
? ? ? ? ? ? ],
? ? ? ? ? ),
? ? ? ? ));
? }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論