Nealyang/PersonalBlog

沸点 UI & 功能 编写(下)

Nealyang opened this issue · 0 comments

前言

上一章节中,我们完成了沸点页面部分UI的编写,这一章节,我们将完成沸点页面剩余页面的代码编写

cell组件编写

通过拿到的cell数据去判断为哪一类cell

  widget.pinsCell.url == ''
                    ? PinsCellPic(
                        pics: widget.pinsCell.pictures,
                      )
                    : PinsCellUrl(
                        url: widget.pinsCell.url,
                        urlPic: widget.pinsCell.urlPic,
                        urlTitle: widget.pinsCell.urlTitle,
                      ),
  • 当cell中的数据包含url这个的时候,说明是link类型的cell

cell类型的UI编写比较简单,我们将完成如下的UI编写
img

  • lib/widget/pins_cell_url.dart
  @override
    Widget build(BuildContext context) {
      return InkWell(
        onTap: (){
          Application.router.navigateTo(context,"/web?url=${Uri.encodeComponent(url)}&title=${Uri.encodeComponent(urlTitle)}");
        },
            child: Container(
            padding: const EdgeInsets.all(10.0),
            margin: const EdgeInsets.symmetric(horizontal: 14.0,vertical: 10.0),
            height: 100,
            decoration: BoxDecoration(
                border:
                    Border.all(color: Theme.of(context).accentColor, width: 1.0),
                borderRadius: BorderRadius.all(Radius.circular(4.0))),
            child: Row(
              children: <Widget>[
                Expanded(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
  
                    children: <Widget>[
                      Text(
                        urlTitle,
                        style:
                            TextStyle(fontSize: 19.0, fontWeight: FontWeight.bold),
                        maxLines: 2,
                        overflow: TextOverflow.ellipsis,
                      ),
                      Text(
                        url,
                        style: TextStyle(
                            fontSize: 15.0, color: Theme.of(context).accentColor),
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ],
                  ),
                  flex: 2,
                ),
                Expanded(
                  flex: 1,
                  child: Image.network(urlPic),
                )
              ],
            )),
      );
    }
  • 最外层使用InkWell包裹,这个应该不默认,其实就是为了绑定点击事件,点击后,跳转到链接地址
  • 外层通过Container 包裹,去设置一些样式,比如padding、margin、height以及border的设置
  • 里面我们通过Row去横向排列子组件,里面我们使用Expanded组件,是为了能够完全的撑开Row的内容

图片查看页面

下面我们新建一个页面,用于查看图片

  • lib/pages/swip_page.dart

    @override
    Widget build(BuildContext context) {
      List picList = pics.split(',');
      int index = int.parse(currentIndex);
      return Center(
          child: Swiper(
            itemBuilder: (BuildContext context, int index) {
              return new Image.network(
                picList[index],
                fit: BoxFit.fitWidth,
                width: MediaQuery.of(context).size.width,
              );
            },
            itemCount: picList.length,
            scale: 0.8,
            pagination: new SwiperPagination(),
            index: index,
            onTap: (index) {
              Application.router.pop(context);
            },
          ),
        );
    }
  • 这里我们引入flutter package:flutter swiper。关于如何引入以及查找相关package,之前已经介绍过,这里就不多说了。
  • 设置itemCount为我们传入的图片数目。并且设置指示器
  • 点击页面的时候,退出页面

lib/routers 下注入相关页面后,即可来编写cell的图片部分,并完成页面的跳转以查看图片

  • lib/widget/pins_cell_pic.dart
  @override
    Widget build(BuildContext context) {
      if (pics.length > 3) {
        _picHeight = 190.0;
      }
      for (int i = 0; i < pics.length; i += 3) {
        List<Widget> _tempRow = List();
        _tempRow.add(
          Expanded(
            child: InkWell(
              onTap: () {
                Application.router.navigateTo(context,
                    '/swip?pics=${Uri.encodeComponent(_buildPicsStr())}&currentIndex=${i.toString()}',transition: TransitionType.fadeIn);
              },
              child: Image.network(
                pics[i],
                fit: BoxFit.cover,
                height: _picHeight,
              ),
            ),
            flex: 1,
          ),
        );
        if (i + 1 < pics.length) {
          _tempRow.add(
            SizedBox(
              width: 10.0,
            ),
          );
          _tempRow.add(
            Expanded(
              child: InkWell(
                onTap: () {
                  Application.router.navigateTo(context,
                      '/swip?pics=${Uri.encodeComponent(_buildPicsStr())}&currentIndex=${i.toString()}');
                },
                child: Image.network(
                  pics[i + 1],
                  fit: BoxFit.cover,
                  height: _picHeight,
                ),
              ),
              flex: 1,
            ),
          );
        }
        if (i + 2 < pics.length) {
          _tempRow.add(
            SizedBox(
              width: 10.0,
            ),
          );
          _tempRow.add(
            Expanded(
              child: InkWell(
                onTap: () {
                  Application.router.navigateTo(context,
                     '/swip?pics=${Uri.encodeComponent(_buildPicsStr())}&currentIndex=${i.toString()}');
                },
                child: Image.network(
                  pics[i + 2],
                  fit: BoxFit.cover,
                  height: _picHeight,
                ),
              ),
              flex: 1,
            ),
          );
        }
        _wrapChildren.add(Container(
          child: Row(
            children: _tempRow,
          ),
          margin: const EdgeInsets.only(bottom: 10.0),
        ));
      }
  
      return Container(
        margin: const EdgeInsets.symmetric(vertical: 10.0),
        child: Wrap(
          children: _wrapChildren,
        ),
      );
    }
  • 首先我们需要注意的是,这里我们不能使用GridView来实现我们的图片,除非我们能够给最外层一个限定高度的Container,但是,根据我们页面的UI,这个高度是不能固定的。且,当我们给定了Container一个固定高度,Container内容还是会有滚动标签在。所以这里我们不适用GridView布局。
  • 点击跳转页面,并且传递当前点击的图片的index
  • 根据图片的数目不同,设置不同的图片高度。
  • 跳转页面的时候,使用了TransitionType.fadeIn来设置页面的跳转动画,这些大家都可以自行设置查看相应效果。注意TransitionType属于fluro的方法,所以使用时需要引入包:import 'package:fluro/fluro.dart';

完成代码查看:代码地址

效果如如下:

swip

代码中同级目录包括沸点cell的底部 点赞和评论的widget的编写,地址为:lib/widget/pins_cell_bottom_button.dart 代码比较简单也比较常规,大家可以自行查看编写相应UI。

cell widget 组合

完成了沸点cell的每一个小部分的代码编写,下面将这些小组件拼接成我们完整的一个沸点的cell吧

  • lib/widgets/pins_list_cell.dart
    @override
    Widget build(BuildContext context) {
      return Container(
        color: Colors.white,
        margin: const EdgeInsets.only(top: 10.0),
        child: Column(
          children: <Widget>[
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 9.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.max,
                children: <Widget>[
                  PinsCellHeader(
                      userInfo: widget.pinsCell.user,
                      createdAt: widget.pinsCell.createdAt),
                  _renderContent(widget.pinsCell.content),
                  widget.pinsCell.url == ''
                      ? PinsCellPic(
                          pics: widget.pinsCell.pictures,
                        )
                      : PinsCellUrl(
                          url: widget.pinsCell.url,
                          urlPic: widget.pinsCell.urlPic,
                          urlTitle: widget.pinsCell.urlTitle,
                        ),
                  widget.pinsCell.topic.length == 0
                      ? Container()
                      : PinsCellTopic(
                          topicInfo: widget.pinsCell.topic,
                        ),
                ],
              ),
            ),
            PinsCellBottomButton(
              commentCount: widget.pinsCell.commentCount,
              likedCount: widget.pinsCell.likedCount,
            ),
          ],
        ),
      );
    }

这部分代码就是将我们编写的所有颗粒度非常小的widget组合使用成我们需要的UI。

总结

如上,我们就完成了沸点部分的编写。需要注意的是,这部分UI非常的多而杂。但是其实难度都不是很大,将大的页面,细分为一个一个颗粒度非常细的组件使我们应该学会的。注意,一定要根据自己的理解、业务的需求去合理划分组件。不可盲目细化导致杂乱。

项目地址