美文网首页Flutter圈子Flutter
Flutter boring coding—创建一个文章列表

Flutter boring coding—创建一个文章列表

作者: Eason_0cce | 来源:发表于2020-01-24 12:05 被阅读0次

    Flutter boring coding是效仿Flutter官方Youtub视频专题“The Boring Flutter Development Show”,结合本人理解推出的系列专题。会持续更新。

    既然是系列,我们先在andriod studio创建一个单独Flutter项目。(只有安装了Flutter跟Dart插件后才有Flutter项目选项)


    image.png
    image.png

    后几步都是点点点就不说了。

    以windows系统为例,项目打开之后,咱们先打开一个模拟器:


    image.png
    image.png

    直到出现这样的界面就说明Flutter实例项目启动成功了。


    image.png

    转到项目,直接看到项目核心文件main.dart


    image.png

    我的目的不是研究他的代码,咱们把main.dart项目中占位置的注释都删了,顺便把他的页面元素即widget来个净化。

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: '文章列表'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child:Text('123')
          ),
        );
      }
    }
    
    

    ctr+s 会看到模拟器展示跟着改变了,Flutter这点我非常喜欢,直接热重载。

    看到我们之前1.0.1示例图,我第一反应想到的是用Column来做父级容器。于是改造_MyHomePageState部分的代码

    这里提出一个有趣的小技巧,鼠标点一下Text组件,按住ctr+enter会出现这样的弹出菜单,我选择了第一个选项,然后输入了Container,是不是快速实现了一个Container组件的包裹,可能你会说这有啥,当你碰到很恐怖的树状的界面你就会发现这个东西的用处了。 image.png

    还有个问题包是包起来了,但是格式调整还是麻烦啊


    image.png

    对了前面我说的是Column,所以我改一下。

    return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Column(
            children: <Widget>[
              Text("列表元素")
            ],
          )
        );
    

    前面说的是文章列表,那么我这边需要造点文章列表数据,新建数据文件。这里是循序渐进的文章讲解,所以不用服务端数据,先用本地写死的数据。


    image.png

    这里有个小技巧,如果你想要新建文件夹加文件,直接这么写


    image.png
    不用多说看截图
    image.png

    数据文件代码:

    final articles = [
      Article(
        text: "Flutter自定义Appbar",
        description : "起初想到这个需求,是因项目中有头部定制化的功能。于是硬着头皮去搜索,最终实现了,我的效果图展示只是一个我做成的样子。实际上这是一个通用解决方案",
        domain: "https://www.jianshu.com/p/14b70d345862",
        by: "Easonyu"
      ),
      Article(
          text: "Flutter文件上传和下载",
          description : "先说说我为了测试文件上传和下载做了哪些前期准备吧,首先我把我的个人域名申请了一张ssl证书(https),然后我自己写了一个文件上传接口(php)",
          domain: "https://www.jianshu.com/p/e867567dd2ff",
          by: "Easonyu"
      ),
      Article(
          text: "Flutter中文官网2",
          description:"开篇先分享一个优秀的dart语法的学习基地:http://codingdict.com/article/21908我在这里面边学边写dart语法还是蛮开心的",
          domain: "https://www.jianshu.com/p/80b736ac5448",
          by: "Easonyu"
      ),
      Article(
          text: "Flutter中文官网3",
          domain: "https://www.jianshu.com/p/c1854a4de4c1",
          description :"继前篇flutter初探之后,此次我来聊聊从传统web项目角度剖析我是怎么一步步搭建flutter基础项目的。本文主要讲述如何实现flutter用户数据多页面共享,用户数据本地缓存",
          by: "Easonyu"
      ),
      Article(
          text: "Flutter初探",
          domain: "https://www.jianshu.com/p/f66cd0e23cfa",
          description :"作为一名长期web前端开发,这次涉及app开发,我自我感觉确实有点膨胀。本篇我主要是以web开发者在flutter开发摸索中碰到的一些问题,进行记录",
          by: "Easonyu"
      )
    ];
    class Article {
      final String text;
      final String description;
      final String domain;
      final String by;
      Article({
        this.text,
        this.description,
        this.domain,
        this.by
      });
    }
    

    在main.dart中引入数据源:

    import 'src/articles.dart';
    

    改造_MyHomePageState:

    return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Column(
            children: articles.map((article)=>Text(article.text)).toList(),
          )
        );
    

    运行结果如图:


    image.png

    按照中文排列方式改造一下:

    return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.start,//左对齐
            children: articles.map((article)=>Text(article.text)).toList(),
          )
        );
    

    运行结果:


    image.png

    问题来了,如果我想要标题之外的其他元素我该如何去做?
    第一步增加_BuildItem Widget扩展渲染方法:

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.start,//左对齐
            children: articles.map(_BuildItem).toList(),
          )
        );
      }
      Widget _BuildItem(Article article){ //用js的方式去理解的话就是这里的_BuildItem替代了原有的箭头函数,并且_BuildItem的类型是Widget(与Flutter中一切皆Widget理念高度吻合)
        return Text(article.text);
      }
    }
    

    第二部宽展_BuildItem丰富界面

    Widget _BuildItem(Article article){
        return Padding(
          padding: EdgeInsets.all(20.0),
          child: ListTile(
            title: Text(article.text),
            subtitle: Text(article.description),
          ),
        );
      }
    

    运行结果如下:


    image.png

    咱们来对标题和内容做一些修饰:

    Widget _BuildItem(Article article){
        return Padding(
          padding: EdgeInsets.all(20.0),
          child: ListTile(
            title: Text(article.text, style: TextStyle(fontSize: 30.0),), //修改字体大小
            subtitle: Text("简介:${article.description}", style: TextStyle(fontSize: 24.0)),
          ),
        );
      }
    

    保存运行:


    image.png

    页面高度溢出了,回想一下,之前的我们外部容器用的Column,两点有问题,第一高度超出会出现溢出问题,第二超出内容我们也无法查看,于是我们用ListView替换掉它。


    image.png

    列表完成了,下面我们添加链接:
    第一步添加页面记载的插件:


    image.png

    记得后面点一下package get。

    这里有个小技巧,不同的Flutter SDK需要安装的插件版本也不一样,如果只是单纯的练习Coding可以在查看版本后面写any


    image.png

    到这里就实现了一个可以打开页面的文章列表。

    为了跟原文同步,我这边继续改造展示部分_BuildItem:

    return ExpansionTile(
            title:Text(article.text),
            children: <Widget>[
              Padding(
                  padding:EdgeInsets.all(20.0),
                  child: Text("简介:${article.description}"),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text("作者:${article.by}"),
                  IconButton(
                    icon: Icon(Icons.launch),
                    color: Colors.green,
                    onPressed: () async{
                      if(await canLaunch(article.domain)){
                        launch(article.domain);
                      }
                    },
                  )
                ],
              )
            ],
        );
    

    运行结果如下:


    image.png

    通常列表数据都要配合下拉刷新,这里,我们用RefreshIndicator
    运行结果如下:


    image.png

    页面完整代码如下:

    import 'package:flutter/material.dart';
    import 'src/articles.dart';
    import 'package:url_launcher/url_launcher.dart';
    import 'dart:io';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: '文章列表'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: RefreshIndicator(
            onRefresh: () async{
              await Future.delayed(Duration(seconds: 1));
              setState(() {
                articles.removeAt(0); //这里要注意跟其他语言setState区分,这里的setState主要做的是通知工作,不需要设置值
              });
            },
            child: ListView(
              children: articles.map(_BuildItem).toList(),
            ),
          )
        );
      }
      Widget _BuildItem(Article article){
        return ExpansionTile(
            title:Text(article.text),
            children: <Widget>[
              Padding(
                  padding:EdgeInsets.all(20.0),
                  child: Text("简介:${article.description}"),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text("作者:${article.by}"),
                  IconButton(
                    icon: Icon(Icons.launch),
                    color: Colors.green,
                    onPressed: () async{
                      if(await canLaunch(article.domain)){
                        launch(article.domain);
                      }
                    },
                  )
                ],
              )
            ],
        );
      }
    }
    
    

    文章总结:
    1.实现了一个可以滚动的列表页
    2.实现了自定义组建渲染
    3.实现了下拉刷新
    4.实现了列表到详情演示

    相关文章

      网友评论

        本文标题:Flutter boring coding—创建一个文章列表

        本文链接:https://www.haomeiwen.com/subject/ifmuzctx.html