從原生開發(fā)到Flutter教程(三)UI框架構(gòu)建及網(wǎng)絡(luò)請求

這是系列文章的第三篇萌焰,為了更快上車颤霎,建議按照順序猪钮,將前兩篇文章通讀一遍获印。
從原生開發(fā)到Flutter教程(一)認(rèn)識Flutter
從原生開發(fā)到Flutter教程(二)新聞列表布局
前面我們已經(jīng)了解了Flutter的基本知識述雾,比如Widget概念、布局理念、UI構(gòu)建思想等玻孟,這篇文章唆缴,我們來一起搭建一下UI框架,完善一下首頁取募,從網(wǎng)絡(luò)獲取真實數(shù)據(jù)渲染列表。

搭建UI基礎(chǔ)框架

iOS為例蟆技,一款應(yīng)用的UI基礎(chǔ)框架玩敏,通常以TabBarController+NavigationController結(jié)合實現(xiàn)的。
TabBarControllerTab控制器质礼,管理著應(yīng)用的Tab模塊旺聚,如微信的微信、通訊錄眶蕉、發(fā)現(xiàn)砰粹、我一共4個Tab模塊。在iOS中造挽,實現(xiàn)TabBarController的思想邏輯非常簡單碱璃,他的viewControllers即模塊控制器集合,tabBar即展示在應(yīng)用底部的Tab欄視圖饭入。
NavigationController即導(dǎo)航控制器嵌器,一般進(jìn)入二級+頁面有兩種方式,一種是導(dǎo)航push谐丢,另一種是modal present爽航,前者更常用,覆蓋95%+場景乾忱。它的實現(xiàn)思想就是壓棧彈棧讥珍,即FILO
說回Flutter窄瘟,基礎(chǔ)UI構(gòu)建框架的思想基本等同于上述衷佃,但是具體的實現(xiàn)方式,有著不小的差別蹄葱。

TabBar

上文我們也已經(jīng)說過纲酗,在寫Flutter的時候,如果不加留意新蟆,就會容易出現(xiàn)代碼冗長觅赊、可讀性差、深陷各種括號難以自拔等等問題琼稻,所以吮螺,我們要時刻注意抽象封裝、代碼構(gòu)建組裝方式,不能因為所謂的寫Flutter就像是堆積木我們就真的將代碼寫的也跟堆積木一樣鸠补。如果不注重代碼質(zhì)量萝风,真的是無腦編碼一時爽,后期維護(hù)火葬場紫岩。

1规惰、簡單分析
TabBar

如上圖,典型的TabBar布局泉蝌,FlutterTabBar構(gòu)建方式跟原生不太一樣歇万,畢竟聲明式編程與命令式編程還是有著本質(zhì)的區(qū)別。
先創(chuàng)建文件夾pages勋陪,再創(chuàng)建MainTabPage.dart文件放入該文件夾贪磺,如下:

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

我們就是在MainTabPage.dart文件中添加Tab邏輯,實現(xiàn)整個App的Tab層UI框架诅愚。
Flutter中寒锚,要想實現(xiàn)Tab,需要使用到TabController违孝、TabBarView刹前、TabBar、Tab等類雌桑。
我們先簡略了解一下:

  • TabController
    管理TabBar腮郊、tabBarView所需狀態(tài)的管理類,一般在項目中我們會實例化一個筹燕,當(dāng)然也可以用系統(tǒng)默認(rèn)的DefaultTabController轧飞。
  • TabBarView
    用于展示其子模塊頁面,他的children屬性就是子頁面的容器撒踪。
  • TabBar
    展示在App底部的Tab選項視圖过咬,在這個類中可以設(shè)置顏色、選中效果之類的屬性制妄。他有個tabs<Tab>屬性掸绞,是放置Tab(Tab按鈕單元控件)的容器。
  • Tab
    添加到TabBar上的按鈕單元控件耕捞,他有text衔掸、icon、child等屬性俺抽。
2敞映、使用系統(tǒng)原生TabBar編碼

先上代碼,后面再分析:

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

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

class _MainTabPageState extends State<MainTabPage>
    with SingleTickerProviderStateMixin {
  TabController _tabController;
  final List<Tab> _tabs = <Tab>[
    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(),
      ),
    );
  }
}

上面代碼有兩個需要注意的點:

  • 一是設(shè)置TabBar是放置在ScaffoldbottomNavigationBar里面而不是寫在AppBarbottom里面磷斧。
  • 另個就是State類要with SingleTickerProviderStateMixin振愿。
    混入了SingleTickerProviderStateMixin類來實現(xiàn)動畫漸變效果捷犹。我們知道,動畫效果為了細(xì)膩真實冕末,控件需要跟屏幕的刷新幀率(FPS)保持同步更新才可以達(dá)到好的效果萍歉。而我們的Tab組件需要滾動漸變等動畫效果,所以MixinSingleTicker档桃。
    這里就談到了Mixin的概念枪孩,Mixin的出現(xiàn)是為了解決一個編程語言的難題的,就是多重繼承的問題藻肄。由于多重繼承的特性雖然靈活強(qiáng)大蔑舞,但是由于其具有結(jié)構(gòu)復(fù)雜化、優(yōu)先順序模糊仅炊、功能沖突等問題斗幼,使得面向?qū)ο蟮氖澜绺渝e綜復(fù)雜澎蛛,所以為能夠利用多繼承的優(yōu)點又解決多繼承的問題抚垄,提出了規(guī)格繼承和實現(xiàn)繼承這兩樣?xùn)|西。比如Java中的interface即規(guī)格繼承谋逻,只聲明呆馁,不實現(xiàn)。而Mixin即實現(xiàn)繼承毁兆,不光繼承了方法名還允許有方法的實現(xiàn)浙滤。
    某種程度上,繼承強(qiáng)調(diào)I am气堕,而Mixin則強(qiáng)調(diào)I can纺腊。

上面一段補充了下DartMixin相關(guān)概念,由于本教程沒有單獨講解Dart語法的章節(jié)茎芭,所以Dart相關(guān)知識會穿插在各個小模塊講解揖膜,這樣可以直接學(xué)以致用,利于記憶梅桩。

寫完了代碼壹粟,我們懷著無比激動的心情,運行一下宿百,看看是不是我們想要的效果趁仙。
flutter run后,WTF!!! 怎么長這個樣子垦页?

Tab首次運行

3雀费、自定義TabBar

無論是高度還是樣式,都顯然不是我們想要的痊焊,接下來坐儿,我們自定義Tab控件律胀。Flutter自定義控件的思想就是,先打散個組件各自實現(xiàn) 貌矿,再組裝在一起炭菌。
我們先如下創(chuàng)建文件:

-lib/components
-lib/components/ZKTabBar,dart // 為了避免跟系統(tǒng)控件沖突,以自己的名字作為前綴逛漫。

直接上代碼:

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

class ZKTabBar extends StatelessWidget {
  final TabController tabController;
  final List<ZKTab> tabs;

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

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 50.0,
      color: Color(0xfff8f8f8),
      child: Column(
        children: <Widget>[
          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: <Widget>[
          Icon(icon),
          Text(
            this.title,
            style: TextStyle(fontSize: 11.5, height: 0.9, fontWeight: FontWeight.w400),
          ),
        ],
      ),
    );
  }
}

封裝好自定義TabBar后黑低,我們在MainTabPage.dart就直接使用就行了。
import酌毡,將ScaffoldbottomNavigationBar屬性直接修改成下面即可完成自定義組件嵌入克握。

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

再次運行,效果完美枷踏。即此TabBar搭建完畢菩暗。

自定義TabBar

新聞列表頁網(wǎng)絡(luò)數(shù)據(jù)加載

在前面我們?yōu)榱丝焖倏葱Ч褂玫氖潜镜丶贁?shù)據(jù)旭蠕。這個小節(jié)我們加載網(wǎng)絡(luò)數(shù)據(jù)渲染頁面停团。
首先,我們新創(chuàng)建一個頁面掏熬,HomeNewsListPage.dart

-lib/pages/HomeNewsListPage.dart

這個頁面就是我們的新聞列表首頁佑稠,在這個文件里面我們請求網(wǎng)絡(luò)數(shù)據(jù)渲染頁面。渲染邏輯前面已經(jīng)講過了旗芬,就是用ListView渲染列表舌胶,這里我們重點講一下網(wǎng)絡(luò)請求。

1疮丛、異步網(wǎng)絡(luò)請求

我們使用Dart提供的網(wǎng)絡(luò)框架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 response.transform(utf8.decoder).join();
  Map dataDict = json.decode(responseBody);

上面代碼,每一行都比較好理解誊薄,值得注意的是履恩,好多處地方都出現(xiàn)了await,我們下面來重點講一下:
Dart中的async/awaitJavaScript中的async/await功能和用法幾乎等同暇屋。在處理異步任務(wù)時似袁,大部分的編程語言的解決思路就是,提供一個回調(diào)函數(shù)咐刨,一般都會在異步處理完成的時候通過回調(diào)函數(shù)來告知調(diào)用者結(jié)果昙衅。不難想象,如果代碼中有大量異步邏輯定鸟,并且出現(xiàn)大量異步任務(wù)依賴其它異步任務(wù)的結(jié)果時而涉,必然會出現(xiàn)Future.then回調(diào)中套回調(diào)情況。舉個例子联予,驗證完信息獲取下載鏈接啼县,下載數(shù)據(jù)材原,然后存入數(shù)據(jù)庫。

verify(token).then((fileUrl) {
  downloadFile(fileUrl).then((file) {
    saveToDatabase(file).then((success){
      print('存儲數(shù)據(jù)成功季眷!');
    });  
  });
});

那問題來了余蟹,怎么消除這種回調(diào)地域呢?
JS/Dart給出的答案就是:async/await組合子刮。
他們可以讓異步任務(wù)如同同步任務(wù)一樣處理威酒。直接上代碼:

void task() async {
  var fileUrl = await verify(token);
  var file = await downloadFile(fileUrl);
  var result = await saveToDatabase(file);
  print('存儲數(shù)據(jù)成功!');
}

相信你很快就會愛上這套寫法挺峡。
總結(jié)幾個關(guān)鍵點:

  • async關(guān)鍵字表示該函數(shù)是異步函數(shù)葵孤,即該函數(shù)會放進(jìn)異步隊列中執(zhí)行,異步隊列具有開啟線程的能力橱赠,所以不會阻塞當(dāng)前線程尤仍。async函數(shù)可以返回一個Future對象,當(dāng)然也可以不返回狭姨。外部收到Future對象后可以調(diào)用then方法實現(xiàn)鏈?zhǔn)秸{(diào)用宰啦,如下:
verify(token).then((fileUrl){
      return downloadFile(fileUrl);
}).then((file){
    return saveToDatabase(file);
}).then((e){
   //執(zhí)行接下來的操作 
}).catchError((e){
  //錯誤處理  
  print(e);
});
  • await后面是一個Future,表示等待該異步任務(wù)完成送挑,異步完成后才會往下走绑莺;注意:await必須出現(xiàn)在async函數(shù)內(nèi)部暖眼。
  • 無論是在JavaScript還是Dart中惕耕,async/await都只是一個語法糖,編譯器或解釋器最終都會將其轉(zhuǎn)化為一個Promise(Future)的調(diào)用鏈诫肠。
2司澎、創(chuàng)建模型,解析數(shù)據(jù)

講解完了HttpClient的用法栋豫,接下來挤安,我們解析網(wǎng)絡(luò)數(shù)據(jù)成為自己的模型數(shù)據(jù),方便渲染頁面和用戶交互的時候使用丧鸯。

  • 先創(chuàng)建一個模型類NewsModel.dart蛤铜。
-lib/models
-lib/models/NewsModel.dart
  • 編寫模型類代碼
    這里的邏輯跟原生開發(fā)的模型類的邏輯一樣,無非就是一些模型屬性的聲明和提供一些JSON轉(zhuǎn)模型的方法丛肢。代碼如下:
// NewsModel.dart
class NewsModel {
  final String title;
  final DateTime publishDate;
  final String imgUrlString;
  NewsModel({
    this.title,
    this.publishDate,
    this.imgUrlString,
  });
  static NewsModel fromDict(Map<String, dynamic> map) {
    NewsModel model = NewsModel(
      title: map['itemTitle'] ?? '新聞標(biāo)題解析異常',
      publishDate:
          DateTime.fromMillisecondsSinceEpoch(int.parse(map['pubDate'])),
      imgUrlString: ((map['itemImageNew'] as List).first as Map)['imgUrl'],
    );
    return model;
  }
}

  • 解析網(wǎng)絡(luò)數(shù)據(jù)到模型
    創(chuàng)建好模型后围肥,我們回到HomeNewsListPage.dart,來編寫請求網(wǎng)絡(luò)數(shù)據(jù)和解析模型的代碼蜂怎。

這里為了便于展示穆刻,我們直接將請求網(wǎng)絡(luò)數(shù)據(jù)和解析的代碼寫在了...Page.dart文件中,在日常原生開發(fā)中可能很多情況都是這么寫的杠步,在iOS中即寫在了ViewController中氢伟,事實上這種寫法無可厚非榜轿。但是,后期一旦業(yè)務(wù)代碼繁重朵锣,Page.dart代碼即要負(fù)責(zé)頁面渲染谬盐,又要負(fù)責(zé)數(shù)據(jù)獲取與解析,就會變得越發(fā)笨重诚些,造成職責(zé)模糊设褐,可讀性差,違背單一職責(zé)SRP和KISS原則泣刹,顯然不是最佳實踐方案助析。一般的解決方案是多設(shè)計一個層,即Service層椅您,來統(tǒng)一管理這些事情外冀。當(dāng)然,為了便于展示和理解掀泳,我們這里先這么寫雪隧,后期我們講到架構(gòu)層面和數(shù)據(jù)流管理的知識時再調(diào)整代碼。

網(wǎng)絡(luò)請求屬于典型的異步任務(wù)员舵,所以我們提供一個異步函數(shù)來請求數(shù)據(jù)脑沿。

Future<List<NewsModel>> 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');
  HttpClientRequest 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;
}

上面的代碼即完成了數(shù)據(jù)請求與模型轉(zhuǎn)換,我們來分析一下马僻。
(1)首先庄拇,我們使用HttpClient請求數(shù)據(jù)。寫法確實有些笨拙韭邓,沒關(guān)系措近,我們后面會用第三方框架來替代HttpClient
(2)然后我們拿到HttpClientResponse女淑,這是個抽象類瞭郑,通過await response.transform(utf8.decoder).join()將其轉(zhuǎn)換成UTF-8字符編碼json字符串形式,再通過json.decode()json字符串轉(zhuǎn)換為容器對象鸭你,這里是轉(zhuǎn)換為Map屈张。
(3)通過itemList鍵取值并解包為List對象,這就是新聞列表的原始數(shù)據(jù)數(shù)組rawDatas袱巨,通過map函數(shù)將原始數(shù)據(jù)轉(zhuǎn)換為咱們前面自定義的模型數(shù)組即完成了數(shù)據(jù)的解析阁谆。

  • 改造HomeNewsListPage.dartHomeNewsCell.dart代碼使用網(wǎng)絡(luò)數(shù)據(jù)
    我們在initState方法中,請求網(wǎng)絡(luò)數(shù)據(jù)瓣窄,并且數(shù)據(jù)收到后通過setState笛厦,Flutter 會自動更新node節(jié)點完成渲染。
// HomeNewsListPage.dart
class HomeNewsListPageState extends State<HomeNewsListPage> {
  List<NewsModel> 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), // 修改這里裳凸,使用模型中的網(wǎng)絡(luò)圖片
    fit: BoxFit.cover,
    ),
  ),
),
3贱鄙、效果展示
網(wǎng)絡(luò)數(shù)據(jù)展示

總結(jié)

簡單回顧一下今天學(xué)到的內(nèi)容,首先我們搭建了App的UITab框架姨谷,由于系統(tǒng)的TabBar樣式不是我們想要的逗宁,所以我們自定義了TabBar控件。從自定義控件的實踐中我們會更加清晰認(rèn)識到Flutter的布局思想和組件構(gòu)建組裝思想梦湘。
然后瞎颗,我們學(xué)會了網(wǎng)絡(luò)請求數(shù)據(jù),然后刷新頁面捌议。由于網(wǎng)絡(luò)請求屬于異步任務(wù)哼拔,我們順帶學(xué)習(xí)了Dart語言的異步任務(wù)的處理方式,領(lǐng)略了JS/Dart語言中的Promise/Future瓣颅、await倦逐、async的用法。

下篇教程宫补,我們來完善一下新聞首頁的布局檬姥,添加輪播圖、標(biāo)題聯(lián)動視圖粉怕、刷新加載數(shù)據(jù)等健民,然后再實現(xiàn)一下新聞詳情頁。OK贫贝,先就醬恒傻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末葵萎,一起剝皮案震驚了整個濱河市府寒,隨后出現(xiàn)的幾起案子受葛,更是在濱河造成了極大的恐慌悦陋,老刑警劉巖蜈彼,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異俺驶,居然都是意外死亡幸逆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門暮现,熙熙樓的掌柜王于貴愁眉苦臉地迎上來还绘,“玉大人,你說我怎么就攤上這事栖袋∨那辏” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵塘幅,是天一觀的道長昔案。 經(jīng)常有香客問我尿贫,道長,這世上最難降的妖魔是什么踏揣? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任庆亡,我火速辦了婚禮,結(jié)果婚禮上捞稿,老公的妹妹穿的比我還像新娘又谋。我一直安慰自己,他們只是感情好娱局,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布彰亥。 她就那樣靜靜地躺著,像睡著了一般衰齐。 火紅的嫁衣襯著肌膚如雪剩愧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天娇斩,我揣著相機(jī)與錄音仁卷,去河邊找鬼。 笑死犬第,一個胖子當(dāng)著我的面吹牛锦积,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歉嗓,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼丰介,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鉴分?” 一聲冷哼從身側(cè)響起哮幢,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎志珍,沒想到半個月后橙垢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡伦糯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年柜某,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敛纲。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡喂击,死狀恐怖淤翔,靈堂內(nèi)的尸體忽然破棺而出翰绊,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布监嗜,位于F島的核電站琳要,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏秤茅。R本人自食惡果不足惜稚补,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望框喳。 院中可真熱鬧课幕,春花似錦、人聲如沸五垮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽放仗。三九已至润绎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诞挨,已是汗流浹背莉撇。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留惶傻,地道東北人棍郎。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像银室,于是被迫代替她去往敵國和親涂佃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容