我要网赚

导航菜单

网络赚钱教程

网络赚钱教程  原题目:日本例外宣布朝鲜导弹分析概况,是想主动证明一件事

  日媒称,日本当局例外宣布朝鲜近期发射的短程弹道导弹分析结果,试图消除了日韩《军事情报保护协议》被铲除了所激发的担忧。

  据《日本经济音讯》9月11日报道称,韩国8月下旬告知日本铲除《军事情报保护协议》后,日韩防守互助将末尾呈现毛病,无关朝鲜导弹发射情报的互换会受到影响。为此,日本防守省公布了朝鲜以往发射短程弹道导弹的分析结果,表现出“有数的立场”。

  报道称,朝鲜于10日上午7时安排,从安稳南道的价川一带向东发射了2枚飞行物。飞行间隔最远约为330公里。至于该飞行物能否为弹道导弹,美韩两军正展开观察。这是韩国告知日本废除《军事变报保护协定》以后,朝鲜第2次发射飞行物。

▲9月10日,年夜众在韩国首尔火车站不美观看朝鲜发射飞行物的新闻节目。

  朝鲜上次发射飞行物是在8月24日,即韩国告知日本废除《军事变报保护协定》的次日。报道称,当时,日本当局比以往更快地公然了发射消息,且比韩国公然患上更早。报道觉患上,日本盼望借此向国内外夸张,韩国废除《军事情报保护协定》没有产生影响。

  报道指出,日韩与各自都有联盟关连的美国互助,应答朝鲜导弹发射。分析导弹种类以及飞行间隔,离不开日韩同享情报,《军事情报保护协定》在这方面发挥着感化。据悉,2016年该协定签订后,日本的分析本领得到进一步提高。

  但日媒也觉得,既然韩国决议废除《军事情报保护协定》,日本政府就不得不把重点放在减轻变乱影响上,反复夸张“废除协定没有形成影响”,并主动证明这一点。所以,日本政府决议公开朝鲜过去所发射飞行物的情报。防卫省公开了对于5月以后朝鲜合计9次发射的18枚飞行物所做分析结果。

▲材料图片:8月1日,韩国外长康京和(右)在泰国曼谷与日本皮毛河野太郎(左)进行外长谈判。

  日本防卫相岩屋毅在3日的记者会上断言,这些飞行物中至少包括2种新型短程弹道导弹。他说,一种是雷同俄罗斯“伊斯坎德尔”的新型导弹,另一种是朝鲜称为“超大型火箭炮”、飞行距离为350至400公里的新型导弹。他表现,朝鲜另有外形和发射方法雷同美国地对于地导弹“ATACMS”的第3种新型导弹。

  报道称,这些新型导弹具备飞行高度较低,能在末端阶段再俯冲等特色。靠日本现有的海基“范例”-3反导系统和地对空反导导弹“爱国者”-3很难截击。

▲日本安排的“爱国者”-3型导弹

  日本防卫省官员就公开情报的企图指出,“日本必要展现高水准的导弹分析本领”。

  日本官房长官菅义伟10日在记者会上被问及能否按照《军事情报保护协定》与韩邦互换情报时说,“日韩在亲密雷赞同见,乐意继承展开包罗交换情报在内的实在合作”。岩屋毅指出,该协定在11月22日以前仍然有效,“只要《军事情报保护协定》有效,咱们就盼望实在加以应答”。

义务编辑:吴金明

网络赚钱教程这是系列文章的第三篇,为了更快上车,发起按照依次,将前两篇文章通读一遍。 从原生开辟到Flutter教程(一)认识Flutter 从原生开辟到Flutter教程(二)音讯列表布局 后面咱们曾经经了解了Flutter的根本常识,比如Widget见解、布局理念、UI构建脑筋等,这篇文章,咱们来一起搭建一下UI框架,美满一下首页,从收集获患上实在数据渲染列表。 搭建UI底子框架

以iOS为例,一款使用的UI底子框架,凡是因此TabBarController+NavigationController连合实现的。 TabBarController即Tab操纵器,操持着使用的Tab模块,如微信的微信、通信录、发明、我一共4个Tab模块。在iOS中,实现TabBarController的脑筋逻辑十分简单,他的viewControllers即模块操纵器聚集,tabBar即展现在应用底部的Tab栏视图。 而NavigationController即导航控制器,日常进入二级+页面有两种方法,一种是导航push,另一种是modal present,前者更常用,包围95%+场景。它的实现思想便是压栈弹栈,即FILO。 说回Flutter,基础UI构建框架的思想根本同等于上述,可是具体的实现方法,有着不小的差别。 TabBar

上文我们也曾经经说过,在写Flutter的工夫,假如不加留意,就会轻易出当代码冗杂、可读性差、深陷各种括号难以自拔等等题目,所以,我们要时候留意抽象封装、代码构建组装方式,不能因为所谓的写Flutter就像是聚集木我们就真的将代码写的也跟聚集木同样。假如不注意代码品质,真的是无脑编码临时爽,前期保护火葬场。 一、简单分析 TabBar

如上图,典范的TabBar布局,Flutter的TabBar构建方式跟原生不太同 样,毕竟申明式编程与命令式编程还是有实在质的差别。 先创立文件夹pages,再创立MainTabPage.dart文件放入该文件夹,如下:

-lib/pages
-lib/pages/MainTabPage.dart

我们便是在MainTabPage.dart文件中增加Tab逻辑,实现全部App的Tab层UI框架。 在Flutter中,要想实现Tab,必要利用到TabController、TabBarView、TabBar、Tab等类。 我们先年夜略了解一下: TabController 操持TabBar、tabBarView所需形态的管理类,日常在名目中我们会实例化一个,固然也能够用系统默认的DefaultTabController。 TabBarView 用于展现其子模块页面,他的children属性就是子页面的容器。 TabBar 展示在App底部的Tab选项视图,在这个类中能够配置色彩、选中结果之类的属性。他有个tabs属性,是安排Tab(Tab按钮单位控件)的容器。 Tab 增加到TabBar上的按钮单位控件,他有text、icon、child等属性。 二、利用系统原生TabBar编码

先上代码,背面再分析:

// MainTabPage.dart
import 'package:flutter/material.dart';

class MainTabPage extends StatefulWidget {
  @override
  _MainTabPageState createState() => _MainTabPageState();
}

class _MainTabPageState extends State
    with SingleTickerProviderStateMixin {
  TabController _tabController;
  final List _tabs = [
    Tab(
      text: '首页',
      icon: Icon(Icons.home),
    ),
    Tab(
      text: '音讯',
      icon: Icon(Icons.message),
    ),
  ];

  @override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: _tabs.length);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: TabBar(
        labelColor: Colors.blue,
        unselectedLabelColor: Colors.black87,
        controller: _tabController,
        tabs: _tabs,
      ),
      body: TabBarView(
        controller: _tabController,
        children: _tabs.map((Tab tab) {
          return Center(child: Text(tab.text));
        }).toList(),
      ),
    );
  }
}


下面代码有两个必要注意的点: 一是配置TabBar是安排在Scaffold的bottomNavigationBar里面而不是写在AppBar的bottom里面。 另个就是State类要with SingleTickerProviderStateMixin。 混入了SingleTickerProviderStateMixin类来实现动画突变结果。我们知道,动画效果为了精致实在,控件需要跟屏幕的革新帧率(FPS)对于峙同步更新才可以到达好的效果。而我们的Tab组件需要转折突变等动画效果,所以Mixin了SingleTicker。 这里就谈到了Mixin的见解,Mixin的呈现是为了办理一个编程语言的坚苦的,就是多重继承的题目。因为多重继承的特征固然灵活强年夜,可是由于其具备结构宏大化、优先依次含糊、成果辩论等问题,使患上面向东西的全国更加错综宏大,所觉得能够使用多继承的长处又办理多继承的问题,提出了规格继承以及实现继承这两样东西。比如Java中的interface即规格继承,只申明,不实现。而Mixin即实现继承,不但继承了方法名还答应有方法的实现。 某种程度上,继承夸张I am,而Mixin则夸张I can。

下面一段增补了下Dart的Mixin相干概念,由于本教程没有独自讲授Dart语法的章节,所以Dart相干常识会交叉在各个小模块讲授,多么可以间接学导致用,利于记忆。

写完了代码,我们怀着非常冲动的心情,运行一下,看看是不是我们想要的效果。 flutter run后,WTF!!! 怎么样长这个模样? Tab初次运行

三、自定义TabBar

不管是高度还是款式,都明显不是我们想要的,接下来,我们自定义Tab控件。Flutter自定义控件的思想就是,先打散个组件各自实现 ,再组装在一起。 我们先如下创建文件:

-lib/components
-lib/components/ZKTabBar,dart // 为了防备跟系统控件辩论,以本身的名字作为前缀。

间接上代码:

// ZKTabBar.dart
import 'package:flutter/material.dart';

class ZKTabBar extends StatelessWidget {
  final TabController tabController;
  final List tabs;

  ZKTabBar({
    @required this.tabController,
    @required this.tabs,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 50.0,
      color: Color(0xfff8f8f8),
      child: Column(
        children: [
          Container(
            color: Colors.black12,
            height: 0.5,
          ),
          Container(
            height: 49.5,
            child: TabBar(
              labelColor: Color(0xff4574B3),
              indicatorColor: Colors.transparent,
              unselectedLabelColor: Color(0xff333333),
              indicatorSize: TabBarIndicatorSize.label,
              tabs: tabs,
              controller: tabController,
            ),
          ),
        ],
      ),
    );
  }
}

class ZKTab extends StatelessWidget {
  final String title;
  final IconData icon;
  ZKTab({
    @required this.title,
    this.icon,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(top: 8.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Icon(icon),
          Text(
            this.title,
            style: TextStyle(fontSize: 11.5, height: 0.9, fontWeight: FontWeight.w400),
          ),
        ],
      ),
    );
  }
}


封装好自定义TabBar后,我们在MainTabPage.dart就直接使用就好了。 先import,将Scaffold的bottomNavigationBar属性直接改正成上面即可完成自定义组件嵌入。

...
bottomNavigationBar: ZKTabBar(
  tabController: _tabController,
  tabs: _tabs,
),
...

再次运行,效果美满。即此TabBar搭建结束。 自定义TabBar

消息列表页收集数据加载

在后面我们为了快速看效果,使用的是当地假数据。这个小节我们加载网络数据渲染页面。 首先,我们新创建一个页面,HomeNewsListPage.dart

-lib/pages/HomeNewsListPage.dart

这个页面就是我们的新闻列表首页,在这个文件里面我们哀求网络数据渲染页面。渲染逻辑前面已经经讲过了,就是用ListView渲染列表,这里我们重点讲一下网络哀求。 一、异步网络请求

我们使用Dart供给的网络框架HttpClient,使用起来如下:

HttpClient network = HttpClient();
  Uri uri = Uri(
      scheme: 'http',
      host: 'api.cportal.cctv.com',
      path: '/api/rest/navListInfo/getHandDataListInfoNew',
      query: 'id=Nav-9Nwml0dIB6wAxgd9EfZA160510&toutuNum=5&version=1&p=5&n=20');
  HttpClientRequest request = await network.getUrl(uri);
  HttpClientResponse response = await request.close();
  var responseBody = await resp
onse.transform(utf8.decoder).join();
  Map dataDict = json.decode(responseBody);

上面代码,每一行都比力好明白,值得注意的是,好多处中央都呈现了await,我们上面来重点讲一下: Dart中的async/await以及JavaScript中的async/await成果和用法多少乎同等。在处理惩罚异步任务时,大部分的编程语言的解决思路就是,供给一个回调函数,一般都会在异步处理惩罚完成的工夫经过回调函数来告知挪用者效果。不难设想,如果代码中有少量异步逻辑,而且出现少量异步任务依靠此外异步任务的效果时,肯定会出现Future.then回调中套回调环境。举个例子,考证完信息获得下载链接,下载数据,而后存入数据库。

verify(token).then((fileUrl) {
  downloadFile(fileUrl).then((file) {
    saveToDatabase(file).then((success){
      print('存储数据成功!');
    });  
  });
});

那问题来了,怎么样消除了这种回调地区呢? JS/Dart给出的谜底就是:async/await组合。 他们可以让异步任务如同同步任务一样处理。直接上代码:

void task() async {
  var fileUrl = await verify(token);
  var file = await downloadFile(fileUrl);
  var result = await saveToDatabase(file);
  print('存储数据成功!');
}

信任你很快就会爱上这套写法。 总结多少个关键点: async关键字表现该函数是异步函数,即该函数会放进异步队列中实行,异步队列具备开启线程的本领,所以不会阻塞以后线程。async函数可以前往一个Future工具,虽然也可以不前往。外部收到Future对于象后可以挪用then方法实现链式调用,如下:

verify(token).then((fileUrl){
      return downloadFile(fileUrl);
}).then((file){
    return saveToDatabase(file);
}).then((e){
   //实行接下来的操纵 
}).catchError((e){
  //过错处理  
  print(e);
});



await背面是一个Future,表现等待该异步任务完成,异步完成后才会往下走;注意:await必须出如今async函数外部。
不管是在JavaScript还是Dart中,async/await都只是一个语法糖,编译器或者表冥具最终都会将其转化为一个Promise(Future)的调用链。

二、创建模型,分析数据

讲解完了HttpClient的用法,接下来,我们分析网络数据成为本身的模型数据,便利渲染页面和用户交互的时候使用。 先创建一个模型类NewsModel.dart。

-lib/models
-lib/models/NewsModel.dart


编写模型类代码
这里的逻辑跟原生开发的模型类的逻辑一样,不过就是一些模型属性的声明和提供一些JSON转模型的方法。代码如下:

// NewsModel.dart
class NewsModel {
  final String title;
  final DateTime publishDate;
  final String imgUrlString;
  NewsModel({
    this.title,
    this.publishDate,
    this.imgUrlString,
  });
  static NewsModel fromDict(Map map) {
    NewsModel model = NewsModel(
      title: map['itemTitle'] ?? '新闻题目解析十分',
      publishDate:
          DateTime.fromMillisecondsSinceEpoch(int.parse(map['pubDate'])),
      imgUrlString: ((map['itemImageNew'] as List).first as Map)['imgUrl'],
    );
    return model;
  }
}



解析网络数据到模型
创建好模型后,我们回到HomeNewsListPage.dart,来编写请求网络数据和解析模型的代码。


这里为了便于展示,我们直接将请求网络数据和解析的代码写在了...Page.dart文件中,在一样平常原生开发中大约很多环境都是这么写的,在iOS中即写在了ViewController中,究竟上这种写法无可非议。但是,前期一旦营业代码沉重,Page.dart代码即要仔细页面渲染,又要仔细数据获取与解析,就会变得更加轻便,形成职责含糊,可读性差,违背繁多职责SRP和KISS准绳,明显不是最佳实际计划。一般的解定夺划是多计划一个层,即Service层,来统一管理这些事变。当然,为了便于展示和明白,我们这里先这么写,后期我们讲到架构层面和数据流管理的知识时再调停代码。

网络请求属于典范的异步任务,所以我们提供一个异步函数来请求数据。

Future> requestData() async {
  HttpClient network = HttpClient();
  Uri uri = Uri(
      scheme: 'http',
      host: 'api.cportal.cctv.com',
      path: '/api/rest/navListInfo/getHandDataListInfoNew',
      query: 'id=Nav-9Nwml0dIB6wAxgd9EfZA160510&toutuNum=5&version=1&p=5&n=20');
  HttpClientR	equest request = await network.getUrl(uri);
  HttpClientResponse response = await request.close();
  var responseBody = await response.transform(utf8.decoder).join();
  Map dataDict = json.decode(responseBody);

  List rawDatas = dataDict['itemList'] as List;
  var models = rawDatas.map((map) {
    map = map as Map;
    NewsModel model = NewsModel.fromDict(map);
    return model;
  }).toList();
  return models;
}

上面的代码即完成为了数据请求与模型转换,我们来分析一下。 (1)首先,我们使用HttpClient请求数据。写法的确有些笨拙,不妨,我们后面会用第三方框架来更换HttpClient。 (2)而后我们拿到HttpClientResponse,这是个抽象类,经过await response.transform(utf8.decoder).join()将其转换成UTF-8字符编码的json字符串形式,再通过json.decode()将json字符串转换为容器对象,这里是转换为Map。 (3)通过itemList键取值并解包为List对象,这就是新闻列表的原始数据数组rawDatas,通过map函数将原始数据转换为我们前面自定义的模型数组即完成为了数据的解析。 改革HomeNewsListPage.dart和HomeNewsCell.dart代码使用网络数据 我们在initState方法中,请求网络数据,而且数据收到后通过setState,Flutter 会主动更新node节点完成渲染。

// HomeNewsListPage.dart
class HomeNewsListPageState extends State {
  List dataSource = [];

  void requestDataAndReload() async {
    var models = await requestData();
    print('zhoukang===>$models');
    setState(() {
      dataSource = models;
    });
  }

  @override
  void initState() {
    super.initState();
    requestDataAndReload();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('新闻列表'),
      ),
      body: ListView.builder(
        itemCount: dataSource.length,
        itemBuilder: (context, index) {
          return HomeNewsCell(
            model: dataSource[index],
          );
        },
      ),
    );
  }
}

// HomeNewsCell.dart
...
Text(
  model.title, // 改正这里,使用模型的title
  style: TextStyle(
    fontSize: 15.0,
    color: Color(0xff111111),
    ),
  maxLines: 3,
  overflow: TextOverflow.ellipsis,
),
...
Container(
  height: 85.0,
  width: 115.0,
  margin: EdgeInsets.only(top: 3),
  decoration: BoxDecoration(
  color: Color(0xffeaeaea),
  borderRadius: BorderRadius.circular(5.0),
  image: DecorationImage(
    // image: AssetImage('images/news_image.jpg'),
    image: NetworkImage(model.imgUrlString), // 修改这里,使用模型中的网络图片
    fit: BoxFit.cover,
    ),
  ),
),

三、效果展示





网络数据展示

总结

简单回顾一下今日学到的内容,首先我们搭建了App的UITab框架,由于系统的TabBar款式不是我们想要的,所以我们自定义了TabBar控件。从自定义控件的实际中我们会越发清楚认识到Flutter的布局思想和组件构建组装思想。 然后,我们学会了网络请求数据,然后革新页面。由于网络请求属于异步任务,我们顺带进修了Dart语言的异步任务的处理方式,明白了JS/Dart语言中的Promise/Future、await、async的用法。

下篇教程,我们来完善一下新闻首页的布局,添加轮播图、题目联动视图、刷新加载数据等,然后再实现一下新闻概况页。OK,先就酱。

最后编辑于:2019-09-12 19:03作者: admin