Newer
Older
flutterBaseApp / lib / ui / pages / demo / list_page.dart
StephanieGitHub on 9 Feb 2021 4 KB first commit
import 'package:base_app/blocs/list_bloc.dart';
import 'package:base_app/blocs/bloc_provider.dart';
import 'package:base_app/models/models.dart';
import 'package:base_app/ui/widgets/common/list/article_item.dart';
import 'package:base_app/ui/widgets/common/list/header_item.dart';
import 'package:base_app/ui/widgets/common/list/refresh_scaffold.dart';
import 'package:base_app/ui/widgets/common/progress_view_widget.dart';
import 'package:base_app/utils/util_index.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flukit/flukit.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:oktoast/oktoast.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:rxdart/rxdart.dart';

/// 简洁主页面
class ListPage extends StatelessWidget {
  final String labelId;

  const ListPage({Key key, this.labelId}) : super(key: key); // 页面的labelId

  // 图片轮播
  Widget buildBanner(BuildContext context, List<BannerModel> list) {
    if (ObjectUtil.isEmpty(list)) {
      return new Container(height: 0.0);
    }
    return new AspectRatio(
      aspectRatio: 16.0 / 9.0,
      // Swiper 控件
      child: Swiper(
        indicatorAlignment: AlignmentDirectional.topEnd,
        circular: true,
        interval: const Duration(seconds: 5),
        indicator: NumberSwiperIndicator(),
        children: list.map((model) {
          return new InkWell(
            onTap: () {
              LogUtil.e("BannerModel: " + model.toString());
              NavigatorUtil.pushWeb(context,
                  title: model.title, url: model.url);
            },
            child: new CachedNetworkImage(
              fit: BoxFit.fill,
              imageUrl: model.imagePath,
              placeholder: (context, url) => new ProgressView(),
              errorWidget: (context, url, error) => new Icon(Icons.error),
            ),
          );
        }).toList(),
      ),
    );
  }

  // 文章列表
  Widget buildArticleList(BuildContext context, List<ArticleModel> list) {
    if (ObjectUtil.isEmpty(list)) {
      return new Container(height: 0.0);
    }
    // 每个article, 子元素
    List<Widget> _children = list.map((model) {
      return new ArticleItem(
        model,
      );
    }).toList();
    List<Widget> children = new List();
    children.add(new HeaderItem(
      // 列表的头
      leftIcon: Icons.book,
      title: "推荐项目",
      onTap: () {
        showToast("点击推荐项目");
      },
    ));
    children.addAll(_children);
    return new Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: children,
    );
  }

  @override
  Widget build(BuildContext context) {
    // bloc
    final ListBloc bloc = BlocProvider.of<ListBloc>(context);
    RefreshController _controller = new RefreshController();

    // 获取数据
    Observable.just(1).delay(new Duration(milliseconds: 500)).listen((_) {
      bloc.getData(labelId: labelId);
    });

    // 全局
    return new StreamBuilder(
        stream: bloc.bannerStream, // banner stream
        builder:
            (BuildContext context, AsyncSnapshot<List<BannerModel>> snapshot) {
          return new RefreshScaffold(
            labelId: labelId,
            loadStatus: Utils.getLoadStatus(snapshot.hasError, snapshot.data),
            controller: _controller,
            enablePullUp: false,
            onRefresh: ({bool isReload}) {
              return bloc.onRefresh(labelId: labelId);
            },
            child: new ListView(
              children: <Widget>[
                buildBanner(context, snapshot.data), // 轮播广告banner
                // 文章列表
                new StreamBuilder(
                    stream: bloc.articleStream,
                    builder: (BuildContext context,
                        AsyncSnapshot<List<ArticleModel>> snapshot) {
                      return buildArticleList(context, snapshot.data);
                    })
              ],
            ),
          );
        });
  }
}

/// 滑动的数字指示器
class NumberSwiperIndicator extends SwiperIndicator {
  @override
  Widget build(BuildContext context, int index, int itemCount) {
    return Container(
      decoration: BoxDecoration(
          color: Colors.black45, borderRadius: BorderRadius.circular(20.0)),
      margin: EdgeInsets.only(top: 10.0, right: 5.0),
      padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 2.0),
      child: Text("${++index}/$itemCount",
          style: TextStyle(color: Colors.white70, fontSize: 11.0)),
    );
  }
}