Flutter:一小时从零构建一个简单的 App,以及你如何做到这一点!

承香墨影

只分享最有用的原创技术干货!

关注

Hi,大家好,我是承香墨影!

上周 Google 发布了 Flutter 的 Beta 版本,我想将会带起来一波程序员去研究它。

今天分享的文章,就是一个基于 Flutter 的入门文章,作者还是一个学生,在阅读 Flutter 之后,简单的创建了自己的第一个 Flutter App。

虽然很简单,但是依然说明 Flutter 的简洁和快速开发的能力,看看作者是这么做到的吧!

— 承香墨影

作者 | Norbert

翻译 | 承香墨影

授权 承香墨影 翻译并发布

概要

这是一个偶然的事件,我正在浏览我的 Youtube 的订阅内容,看到了很多关于 Flutter 的相关视频,这引起了我的兴趣。我很兴奋的开始阅读它的文档。

我喜欢的学习方式,是边动手边学习。阅读完几页文档并研究如何创建一个新的项目,我对自己尝试新东西,倍感信心。

App

如你在 Gif 中看到的那样,这是一个非常基本的应用程序,但它仍然有一些让我觉得有趣的地方。

  • 它使用 Google Book Api 从数据库中读取书籍数据。

  • 在数据展示前,显示一个加载指示器。

  • 将书名和图像,都加载显示出来。

在传统的 Android App 中,这将需要几个类和不少代码。

而使用 Flutter,这个 App 有一个类和 129 行代码。包括一些引入语句和布局。

这一切,是不是听起来很棒?让我们开始吧!

开始

在我开始之前,我并不会详细的介绍这个 App 的所有细节,请务必查看示例代码以及文档,进行参考。

另外,整个 App 的代码(所有 129 行代码),都在 Github 上开源,我推荐你看看。

https://github.com/Norbert515/BookSearch

List<Book> _items = new List();
final subject = new PublishSubject<String>();
bool _isLoading = false;

在这个例子中,我们需要 3 个变量。

一个书本的列表,其中一般被定义成长这样:

class Book { 
 String title,url;
 Book(this.title,this.url);
}

一个 Public Subject,它是 RxDart 的一部分,而 RxDart 又是 Rx 的一个实现,我这里主要用它来监听 textChanged 事件。

还有一个变量,表示我们目前是否在等待服务端响应。

此外,用户界面包含三个主要元素。

  • 列表

  • 加载器。

  • 文本输入框。

我们将他们放在一起。

new TextField(
   decoration: new InputDecoration(
   hintText: 'Choose a book',
   ),
   onChanged: (string) => (subject.add(string)),
),

关于这个地方的一个有趣的部分是 onChanged,在这里我们传递了一个 Lambda,它讲当前输入的文本添加到 subject 上,这使得我们可以在其他地方监听回调。

_isLoading? new CircularProgressIndicator(): new Container(),

如果当前出于加载状态,则显示进度条,否则显示一个空的容器。

new Expanded(
 child: new ListView.builder(
   padding: new EdgeInsets.all(8.0),
   itemCount: _items.length,
   itemBuilder: (BuildContext context, int index) {
     return new Card(
       child: new Padding(
           padding: new EdgeInsets.all(8.0),
           child: new Row(
             children: <Widget>[
               _items[index].url != null? new Image.network(_items[index].url): new Container(),
               new Flexible(
                   child: new Text(_items[index].title, maxLines: 10),
               ),
             ],
           )
       )
     );
   },
 ),
),

该列表是一个基于索引的 ListView。而在其内部,我们布局了一个用于显示网络图片的 Image 以及一个用于显示书籍描述的 Text

逻辑代码

  @override
 void initState() {
   super.initState();
   subject.stream.debounce(new Duration(milliseconds: 600)).listen(_textChanged);
 }

在这个 initState 方法中,我们使用流式编码来处理它的事件并消费它们。这样做是为了每次点键入文本的时候,不会立即向 Api 服务器发送请求,而是会在最后一次键入文本之后,等待 600ms,再将输入的字符串发送到 _textChange() 方法,这也是我们使用 Rx  的唯一原因。

  void _textChanged(String text) {
   if(text.isEmpty) {
     setState((){_isLoading = false;});
     _clearList();
     return;
   }
   setState((){_isLoading = true;});
   _clearList();
   http.get("https://www.googleapis.com/books/v1/volumes?q=$text")
       .then((response) => response.body)
       .then(JSON.decode)
       .then((map) => map["items"])
       .then((list) {list.forEach(_addBook);})
       .catchError(_onError)
       .then((e){setState((){_isLoading = false;});});
 }

 void _onError(dynamic d) {
   setState(() {
     _isLoading = false;
   });
 }

 void _clearList() {
   setState(() {
     _items.clear();
   });
 }

所有的逻辑都在这里了。

首先说几点,如果 Text 是空的,我们不再加载并消除列表。

另外,如果我们获取到 Text 的内容,我们将开始加载并清除列表。

之后,我们向 Google Api 发出请求 volumes?q=$text ,其中 text 包含当前输入的字符串。

当结果返回的时候:

  • 获得返回的内容。

  • 解析 JSON 数据,饭后返回一个 Map。

  • "items" 包含大量的书籍信息。

  • 循环迭代之后,使用 _addBook() 方法添加到 "items" 中。

  • 这些 "items" 就是我们需要的标题和书籍封面图。

  void _addBook(dynamic book) {
   setState(() {
     _items.add(new Book(book["volumeInfo"]["title"], book["volumeInfo"]["imageLinks"]["smallThumbnail"]));
   });
 }

小结

到这里,该 App 是一个完整的小应用。

这是第一步,接下来将使用一个数据库来存储数据。

  • 我读过这本书吗?

  • 关于这本书的一些笔记内容。

期待你的持续关注。

对今天的分享你觉得如何?有任何问题可以在留言区讨论!

今天在公众号后台回复成长『成长』,将会得到我整理的一些学习资料,也能回复『加群』,一起学习进步。

推荐阅读:

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值