第一次着手用flutter写个程序,我这段程序主要替换flutter-go的轮播图的数据,它给的数据写死在本地的。用过vue与Android,感觉flutter有些不一样。大致看了几篇flutter入门文章,clone阿里提供的学习模板flutter-go。我目的性很强,就想看看爬虫用flutter什么写,正好flutter-go的搜索就是爬360搜索,但是flutter-go把这个功能封装起来,对我这种入门的有点困难,而且我自己也有些懒。主要爬取的网站:h9t.hanju.cc/ , 下面是写这个程序都过程:
flutter插件
主要去 pub.flutter-io.cn/ 网站可以找到一些插件的使用和安装。 爬虫的插件:html 。 用法就跟前端一样的用法,下面是我我仿照flutter-go的代码,爬取 h9t.hanju.cc/ 的轮播图的数据写的代码,最后它请求数据返回的是res:
Future<List<StoryModel>> suggestion() async {
var response = await dio.get("http://h9t.hanju.cc/");
var document = parse(response.data);
var app = document.querySelector(".slide-pic").querySelectorAll("li");
// print('app====>${app}');
List<StoryModel> res = [];
app.forEach((f) {
res.add(
StoryModel(
1,
f.querySelector("a").attributes["title"],
image: f.querySelector("img").attributes["src"],
url: f.querySelector("a").attributes["href"]),
);
});
return Future.delayed(Duration(seconds: 2), () {
return res;
});
Future
这时你看到一个新词Future,引用博客 www.jianshu.com/p/890df7ea8… 解说:简单来说future就是一个Future对象,当执行return await。。。的时候,实际上返回的是一个延迟计算的Future对象,这个Future对象是Dart内置的,有自己的队列策略,它将要操作的事件放入EventQueue中,在队列中的事件按照先进先出的原则去逐一处理事件,当事件处理完成后,将结果返回给Future对象。然后我自己会觉得,我就可以这么用:
List<StoryModel> bannerStories1 = api.suggestion() ;
但是这是报错的代码
人是擅长模仿的,我去看了别的博客使用,最后这么使用是成功:
List<StoryModel> bannerStories=[];
Future _setItem() async{
List<StoryModel> bannerStories = await api.suggestion() ;
print(bannerStories.length);
}
这时不报错了,打印日志bannerStories.length是大于0的,但是你直接在别的地方使用bannerStories是0,这个关于生命周期的问题,请求网络需要时间,你调用是它原本的数据当然是0,就算bannerStories请求数据改变,控件页不改变。最后我想到之前看过一篇文章 juejin.cn/post/684490… 提到过flutter的widget有两种StatefulWidget和StatelessWidget,它们的使用不同。StatefulWidget的有个state在widget的生命周期中可以改变,StatelessWidget自身的状态不会改变,具体的大家可以去了解这篇文章。同时我发现写这个轮播图的控件是继承StatelessWidget,然后我换成StatefulWidget。用setState去通知控件数据改变了,最后实现的代码是:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:async';
import './home_banner.dart';
import '../model/story.dart';
import '../blocs/hanwang_api.dart';
class Pagination extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return new HomeState();
}
}
class HomeState extends State<Pagination> {
@override
void initState() {
// TODO: implement initState
super.initState();
_setItem();
}
void _launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
List<StoryModel> bannerStories=[];
Future _setItem() async{
List<StoryModel> bannerStories1 = await api.suggestion() ;
print(bannerStories.length);
setState(() {
bannerStories = bannerStories1;//可以这么理解通知控件改变数据
});
}
List<Widget> _pageSelector(BuildContext context){
List<Widget> list = [];
if (bannerStories.length > 0) {
list.add(HomeBanner(bannerStories, (story) {
_launchURL('${story.url}');
}));
}
return list;
}
@override
Widget build(BuildContext context) {
return
Column(
key:Key('__header__'),
children: _pageSelector(context)
);
}
}
该网站是用gb2312编码格式有乱码的情况,我页没有找到相应的插件解决。
掘金不能上传gif图啊,可以去我的CSDN查看 blog.csdn.net/qq_34414578… 这个时候就完成了,大概了解flutter,按照这个流程,就可以学下去,有错的,大家多多指正。