flutter 之 ListView控件 支持下拉刷新 滑道底部自動加載更多

效果

實現代碼

import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutterwncq/models/article_data_bean.dart';
import 'package:flutterwncq/utils/net_utils.dart';

class CQInformationPage extends StatefulWidget {
  @override
  _CQInformationPageState createState() => _CQInformationPageState();
}

class _CQInformationPageState extends State<CQInformationPage> {
  var _hasMore = true;
  int curPage = 1;
  List<ListData> _newsList;

  ScrollController _scrollController;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController()
      ..addListener(() {
        ////判斷是否滑到底
        if (_scrollController.position.pixels ==
                _scrollController.position.maxScrollExtent &&
            _hasMore) {
          curPage++;
          _articlePage();
        }
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          '傳奇諮訊',
          style: TextStyle(color: Color(0xffbbbbbb), fontSize: 16.0),
        ),
        centerTitle: true,
        backgroundColor: Color(0xff161616),
        leading: new IconButton(
          icon: new Container(
            padding: EdgeInsets.all(3.0),
            child: new CircleAvatar(
                radius: 15.0,
                backgroundColor: Color(0xff161616),
                backgroundImage:
                    AssetImage("assets/images/nav_icon_return.png")),
          ),
          onPressed: () {
            Navigator.of(context).pop();
          },
        ),
        brightness: Brightness.dark,
      ),
      body: RefreshIndicator(
        onRefresh: _pullToRefresh,
        child: _buildListView(),
      ),
    );
  }

  Future<Null> _pullToRefresh() async {
    curPage = 1;
    _hasMore = true;
    _articlePage();
    return null;
  }

  _buildListView() {
    if (_newsList == null) {
      _articlePage();
      return CupertinoActivityIndicator();
    }
    return ListView.builder(
      itemBuilder: (context, index) {
        if (index == _newsList.length) {
          return Padding(
            padding: const EdgeInsets.all(10.0),
            child: Center(
              child: CupertinoActivityIndicator(),
            ),
          );
        }
        return _newListItem(context, _newsList[index]);
      },
      itemCount: _hasMore ? _newsList.length + 1 : _newsList.length,
      controller: _scrollController,
    );
  }

  _articlePage() {
    var params = new Map<String, dynamic>();
    params['pageNumber'] = curPage;
    params['pageSize'] = 10;
    NetUtils.get('https://tt.weinicq.com/i/index/articlePage', params)
        .then((result) {
      ArticleDataBean data = ArticleDataBean.fromJson(json.decode(result));
      setState(() {
        _hasMore = !data.data.page.lastPage;
        if (curPage == 1) {
          _newsList = data.data.page.list;
        } else {
          _newsList.addAll(data.data.page.list);
        }
      });
    });
  }

  _newListItem(BuildContext context, ListData data) {
    return Container(
      decoration: BoxDecoration(
        border: Border(
          bottom: BorderSide(
            color: Color(0xff0b0b0b),
            width: 5.0,
          ),
        ),
      ),
      child: InkWell(
        onTap: () {},
        child: Container(
          padding: const EdgeInsets.all(15.0),
          color: Color(0xff161616),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Card(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10.0)),
                clipBehavior: Clip.antiAlias,
                child: Image.network(
                  data.picUrl,
                  height: 190.0,
                  width: MediaQuery.of(context).size.width - 30,
                  fit: BoxFit.cover,
                ),
              ),
              /*ClipRRect(
              borderRadius: BorderRadius.circular(15),
              child: Image.network(data.picUrl,height: 190.0,width: MediaQuery.of(context).size.width-30,fit: BoxFit.cover,),
            ),
            Container(
              width: MediaQuery.of(context).size.width-30,
              height: 190.0,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(15.0)),
                image: DecorationImage(
                    image: NetworkImage(data.picUrl,),
                  fit: BoxFit.cover
                )
              ),
            ),*/
              SizedBox(height: 15.0,),
              Text(
                data.title,
                style: TextStyle(
                  color: Color(0xffbbbbbb),
                  fontSize: 13.0,
                ),
                overflow: TextOverflow.ellipsis,
                maxLines: 2,
              ),
              SizedBox(height: 10.0,),
              Text(data.createTime,style: TextStyle(color: Color(0xff666666),fontSize: 12.0),)
            ],
          ),
        ),
      ),
    );
  }
}

javabean


class ArticleDataBean {
  String apiCacheValue;
  Data data;
  String errcode;

  ArticleDataBean({this.apiCacheValue, this.data, this.errcode});

  ArticleDataBean.fromJson(Map<String, dynamic> json) {
    apiCacheValue = json['apiCacheValue'];
    data = json['data'] != null ? new Data.fromJson(json['data']) : null;
    errcode = json['errcode'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['apiCacheValue'] = this.apiCacheValue;
    if (this.data != null) {
      data['data'] = this.data.toJson();
    }
    data['errcode'] = this.errcode;
    return data;
  }
}

class Data {
  Page page;

  Data({this.page});

  Data.fromJson(Map<String, dynamic> json) {
    page = json['page'] != null ? new Page.fromJson(json['page']) : null;
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.page != null) {
      data['page'] = this.page.toJson();
    }
    return data;
  }
}

class Page {
  bool firstPage;
  bool lastPage;
  List<ListData> list;
  int pageNumber;
  int pageSize;
  int totalPage;
  int totalRow;

  Page(
      {this.firstPage,
        this.lastPage,
        this.list,
        this.pageNumber,
        this.pageSize,
        this.totalPage,
        this.totalRow});

  Page.fromJson(Map<String, dynamic> json) {
    firstPage = json['firstPage'];
    lastPage = json['lastPage'];
    if (json['list'] != null) {
      list = new List<ListData>();
      json['list'].forEach((v) {
        list.add(new ListData.fromJson(v));
      });
    }
    pageNumber = json['pageNumber'];
    pageSize = json['pageSize'];
    totalPage = json['totalPage'];
    totalRow = json['totalRow'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['firstPage'] = this.firstPage;
    data['lastPage'] = this.lastPage;
    if (this.list != null) {
      data['list'] = this.list.map((v) => v.toJson()).toList();
    }
    data['pageNumber'] = this.pageNumber;
    data['pageSize'] = this.pageSize;
    data['totalPage'] = this.totalPage;
    data['totalRow'] = this.totalRow;
    return data;
  }
}

class ListData {
  int aid;
  String createTime;
  String creator;
  String picUrl;
  String sendTime;
  String title;

  ListData(
      {this.aid,
        this.createTime,
        this.creator,
        this.picUrl,
        this.sendTime,
        this.title});

  ListData.fromJson(Map<String, dynamic> json) {
    aid = json['aid'];
    createTime = json['createTime'];
    creator = json['creator'];
    picUrl = json['picUrl'];
    sendTime = json['sendTime'];
    title = json['title'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['aid'] = this.aid;
    data['createTime'] = this.createTime;
    data['creator'] = this.creator;
    data['picUrl'] = this.picUrl;
    data['sendTime'] = this.sendTime;
    data['title'] = this.title;
    return data;
  }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章