Flutter 入門指北(Part 2)之基礎(chǔ)部件

該文已授權(quán)公眾號 「碼個蛋」,轉(zhuǎn)載請指明出處

上一節(jié)介紹了 Dart 的一些語法,以及配置環(huán)境的網(wǎng)址唐断,這節(jié)我們就可以開始了解下 Flutter

主要包括 MaterialAppScaffoldText离咐、ImageIcon奉件、Button 以及 AppBar 部分內(nèi)容宵蛀,準(zhǔn)備出發(fā)~

Flutter runApp

新建 flutter 項(xiàng)目后,可以看到 lib 下的 main.dart 中 void main() => runApp(MyApp()); 這句就是程序的入口了县貌。這里可以簡單看下源碼

void runApp(Widget app) {
  WidgetsFlutterBinding.ensureInitialized()
    ..attachRootWidget(app)
    ..scheduleWarmUpFrame();
}

///....
static WidgetsBinding ensureInitialized() {
  if (WidgetsBinding.instance == null)
    WidgetsFlutterBinding();
  return WidgetsBinding.instance;
}

///....
void attachRootWidget(Widget rootWidget) {
  _renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
    container: renderView,
    debugShortDescription: '[root]',
    child: rootWidget
  ).attachToRenderTree(buildOwner, renderViewElement);
}

首先會創(chuàng)建一個 WidgetsBinding 單例對象术陶,然后把傳入的 App 添加到 rootWidget 中,scheduleWarmUpFrame 方法比較長煤痕,這邊看下對該方法的注釋第一句就能了解方法的主要功能了

Schedule a frame to run as soon as possible

「安排框架盡快運(yùn)行起來」(原諒我這渣英語梧宫,只能看懂不會翻譯..大概就是「快速啟動框架」的意思吧)

Flutter App

接著看下 MyApp 這個類,繼承自 StatelessWidget 并在 build 方法返回一個 MaterialApp 實(shí)例杭攻,(偷偷講下祟敛,其實(shí)這邊還可以返回 CupertinoApp疤坝,這是一個 iOS 風(fēng)格的 widget兆解,基本上你看到部件帶 「Cupertino」的都是 iOS 風(fēng)格的 widget,這里先不講 iOS 風(fēng)格的部件跑揉,目前 flutter 對 Cupertino 系列的 widget 支持不是很好锅睛,包括部件的廣度,多語言的支持等等方面都不是很友好历谍,所以我們還是繼續(xù)看 MD 風(fēng)格的 Android 部件吧~)现拒,這里先看下 MaterialApp 的構(gòu)造函數(shù),介紹一些常用的參數(shù)

const MaterialApp({
    Key key,
    this.navigatorKey,
    this.home, // 主界面的內(nèi)容 widget
    this.routes = const <String, WidgetBuilder>{}, // 帶 router 和路由跳轉(zhuǎn)有關(guān)
    this.initialRoute,
    this.onGenerateRoute,
    this.onUnknownRoute,
    this.navigatorObservers = const <NavigatorObserver>[], 
    this.builder,
    this.title = '', // *類似標(biāo)題
    this.onGenerateTitle, // 主要用于多語言情況下望侈,需要根據(jù)當(dāng)前語言替換 title印蔬,需要使用該值
    this.color, // 主題色,如果該值未設(shè)置脱衙,取 theme.primaryColor,未設(shè)置 theme 則取藍(lán)色
    this.theme, // App 的主題風(fēng)格侥猬,包括主題色,按鈕默認(rèn)顏色等等
    this.locale, // 帶 locale 的和多語言適配相關(guān)
    this.localizationsDelegates,
    this.localeListResolutionCallback,
    this.localeResolutionCallback,
    this.supportedLocales = const <Locale>[Locale('en', 'US')],
    this.debugShowMaterialGrid = false, 
    this.showPerformanceOverlay = false,
    this.checkerboardRasterCacheImages = false,
    this.checkerboardOffscreenLayers = false,
    this.showSemanticsDebugger = false,
    this.debugShowCheckedModeBanner = true, // debug 模式下捐韩,是否顯示 DEBUG 標(biāo)示橫幅
  })

MaterialApp 繼承自 StatefulWidget退唠,它和 MyApp 所繼承的類 StatelessWidget,就是日常開發(fā)中荤胁,自定義部件通常繼承的抽象類了瞧预。

  1. StatelessWidget 是狀態(tài)不可變部件,通過其構(gòu)建的部件一般用來展示固定內(nèi)容,例如需要展示固定的功能按鈕列表垢油,不需要根據(jù)不同界面狀態(tài)進(jìn)行修改其展示內(nèi)容
  2. StatefulWidget 是可改變狀態(tài)的部件盆驹,比如我們需要通過網(wǎng)絡(luò)或者數(shù)據(jù)庫獲取數(shù)據(jù),然后修改部件鎖展示的數(shù)據(jù)內(nèi)容秸苗,則需要通過 StatefulWidget 來構(gòu)建召娜。當(dāng)然,不是說 StatelessWidget 不能實(shí)現(xiàn)修改界面數(shù)據(jù)的功能惊楼,這就需要涉及到 狀態(tài)管理 的概念了玖瘸,后面有機(jī)會再講,這邊先埋坑【坑1】

Flutter Scaffold

進(jìn)入 App 后就需要構(gòu)建界面了檀咙,Flutter 提供了 Scaffold 來快速構(gòu)建一個 MaterialDesign 風(fēng)格的界面雅倒,還是先看下 Scaffold 的構(gòu)造函數(shù)吧,了解幾個比較常用的部分弧可。

const Scaffold({
    Key key,
    this.appBar, // 界面頂部的那條欄蔑匣,這邊需要返回一個 AppBar 實(shí)例
    this.body, // 界面的內(nèi)容部分
    this.floatingActionButton, // 懸浮部分,可以通過 floatingActionButtonLocation 設(shè)置位置
    this.floatingActionButtonLocation,
    this.floatingActionButtonAnimator,
    this.persistentFooterButtons,
    this.drawer, // 側(cè)滑抽屜部分棕诵,從左側(cè)滑出(應(yīng)該和語言有關(guān)裁良,和文字方向同向)
    this.endDrawer, // 側(cè)滑抽屜部分,從右側(cè)滑出
    this.bottomNavigationBar, // 底部導(dǎo)航欄校套,就是通臣燮ⅲ看到的底部 TAB 切換部件
    this.bottomSheet, // 展示從底部彈出的,起到提示作用的笛匙,通過 showModalBottomSheet 展示
    this.backgroundColor, // 界面的背景色
    this.resizeToAvoidBottomPadding = true, // 避免 body 被底部彈出部件填充侨把,例如輸入法鍵盤
    this.primary = true, // 當(dāng)前的 Scaffold 是否需要被展示在屏幕最上層
  })

來張圖吧,簡潔明了

scaffold分布.png

了解完 Scaffold 的整體構(gòu)造后妹孙,我們從上到下秋柄,通過構(gòu)造函數(shù)來了解下各個 Widget 的使用方法

AppBar
AppBar({
    Key key,
    this.leading, // 用于設(shè)置 AppBar 前置的按鈕,例如設(shè)置返回我們需要的返回按鈕等
    this.automaticallyImplyLeading = true, // 是否使用系統(tǒng)默認(rèn)生成的按鈕蠢正,如果替換 leading 的默認(rèn)按鈕骇笔,最好將該屬性設(shè)置成 false
    this.title, // AppBar 所需要展示的組件,傳入一個 Widget 實(shí)例嚣崭,通常使用 Text 展示一個標(biāo)題
    this.actions, // AppBar 末尾懸浮的一些操作組件笨触,例如常見的會在末尾設(shè)置一個「...」按鈕,點(diǎn)擊彈出一個 menue 提供給用戶操作選擇
    this.flexibleSpace, // AppBar 的背景有鹿,可以設(shè)置顏色旭旭,背景圖等等 
    this.bottom, // bottom 用于展示頂部導(dǎo)航 TAB
    this.elevation = 4.0,
    this.backgroundColor, // AppBar 的背景色,如果只需要修改顏色葱跋,可以不通過 flexibleSpace 修改
    this.brightness,
    this.iconTheme, // 按鈕的默認(rèn)樣式
    this.textTheme, // 文字的默認(rèn)樣式
    this.primary = true,
    this.centerTitle, // 是否將展示的 title 居中
    this.titleSpacing = NavigationToolbar.kMiddleSpacing, // AppBar title 兩側(cè)的空白間隔
    this.toolbarOpacity = 1.0,
    this.bottomOpacity = 1.0,
  })

在展示 AppBardemo 之前持寄,我們先學(xué)習(xí)幾個基本的組件 Text源梭、ImageIcon稍味、Button 分布用于展示文字废麻,圖片,圖標(biāo)模庐,按鈕

Text
const Text(this.data, { // Text 需要展示的文字
    Key key,
    this.style, // 文字的樣式烛愧,包括顏色,大小掂碱,間距等等屬性怜姿,這邊就不繼續(xù)展示 TextStyle 構(gòu)造函數(shù)了,不然我怕大家都不想繼續(xù)看了疼燥,稍后通過例子來說明
    this.textAlign, // 文字的對齊方式沧卢,包括左對齊,右對齊醉者,居中等但狭,詳見 TextAlign 類
    this.textDirection, // 文字方向,ltr(left to right) 或者 rtl(right to left)
    this.locale, 
    this.softWrap, // 當(dāng)文字一行顯示不完是否換行
    this.overflow, // 如果超出限制的行數(shù)撬即,以哪種方式省略未展示的內(nèi)容
    this.textScaleFactor, // 文字縮放比例
    this.maxLines, // 最多展示的行數(shù)
    this.semanticsLabel,
  })

說了那么多立磁,相信很多小伙伴都要急著擼代碼了吧,接著來展示一些 Text 的示例剥槐,接下來的例子都會直接替換 HomePage 內(nèi)的展示內(nèi)容唱歧,其余都是相同的,接下來請關(guān)注 Text 別的部件先忽略才沧,后面會介紹迈喉,這邊先埋坑【坑2】

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(primarySwatch: Colors.lightBlue),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Container(
          padding: const EdgeInsets.only(top: 10.0),
          child: Center(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('綠色背景黑色文字展示',
                  style: TextStyle(
                      color: Colors.black, // 設(shè)置文字顏色绍刮,不可和 foreground 同時設(shè)置
                      fontSize: 24.0, // 字體大小
                      letterSpacing: 2.0, // 每個字符之間的間隔
                      background: Paint()..color = Colors.green)), // 背景色
              Text('這是一個帶紅色下劃線的文字展示',
                  style: TextStyle(
                      color: Colors.black,
                      fontSize: 24.0,
                      // 文字裝飾線温圆,除了 underline 還有 overline, lineThrough,
                      // 不同的樣式小伙伴可以通過自己修改代碼來查看
                      decoration: TextDecoration.underline,
                      // 文字裝飾線的類型孩革,除了 solid 還有 double,dotted,dashed,wavy 可選
                      decorationStyle: TextDecorationStyle.solid,
                      // 裝飾線的顏色
                      decorationColor: Colors.red))
            ],
          )),
        ));
  }
}

該部分代碼查看源碼 text_main.dart 文件

最后的展示效果如下圖:

text 展示.png
Image

/壞笑 按照慣例岁歉,我們還是先看下 Image 的構(gòu)造函數(shù)吧

const Image({
    Key key,
    // 一個 ImageProvider 實(shí)例,但是 ImageProvider 是一個抽象類膝蜈,F(xiàn)lutter 已經(jīng)給我們提供如下
    // AssetImage锅移,NetworkImage,F(xiàn)ileImage饱搏,MemoryImage 這四種圖片加載器非剃,為了方便調(diào)用
    // 我們可以直接通過 Image.asset, Image.network, Image.file, Image.memory 簡化,
    // 通過方法名推沸,可以看出分別從 asset 文件备绽,網(wǎng)絡(luò)券坞,文件,內(nèi)存中加載圖片
    @required this.image, 
    this.semanticLabel,
    this.excludeFromSemantics = false,
    this.width, // 圖片寬度
    this.height, // 圖片高度
    this.color, // 圖片背景色
    this.colorBlendMode, // color 和圖片的混合模式(這個值比較多肺素,可以一個個嘗試)
    this.fit, // 圖片填充方式 fill, cover, contain, fillWidth, fillHeight, scaleDown, none
    this.alignment = Alignment.center, // 對齊方式
    this.repeat = ImageRepeat.noRepeat, // 若未填充滿空間恨锚,重復(fù)展示的方式
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    this.filterQuality = FilterQuality.low,
  })

好了好了,我知道你們又想自己寫代碼嘗試下了倍靡,在這之前猴伶,需要你先準(zhǔn)備一張本地圖片,然后在項(xiàng)目的根目錄塌西,也就是 lib 文件夾同層他挎,創(chuàng)建一個新的文件夾,命名為 images捡需,把你準(zhǔn)備好的圖片放到這個目錄下雇盖。放好之后打開 pubspec.yaml 把圖片資源文件注冊下

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # 這邊注冊資源文件,以后有圖片文件也可以只注冊 images 文件夾栖忠,會自動讀取內(nèi)部的文件
  assets:
    - images/ali.jpg

注冊完成后崔挖,就可以繼續(xù)愉快的擼代碼了~

class HomePage extends StatelessWidget {
  final String _assetAli = 'images/ali.jpg';
  final String _picUrl =
      'https://timg05.bdimg.com/timg?wapbaike&quality=60&size=b1440_952&cut_x=143&cut_y=0&cut_w=1633&'
      'cut_h=1080&sec=1349839550&di=cbbc175a45ccec5482ce2cff09a3ae34&'
      'src=http://imgsrc.baidu.com/baike/pic/item/4afbfbedab64034f104872baa7c379310b551d80.jpg';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Container(
          padding: const EdgeInsets.only(top: 10.0),
          child: Center(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              // 這種展示圖片方式和下一種會有相同的效果
              Image(image: AssetImage(_assetAli), width: 80.0, height: 80.0),
              // 接下來加載圖片都會使用這些比較方便的方法
              Image.asset(_assetAli, width: 80.0, height: 80.0),
              // 加載一張網(wǎng)絡(luò)圖片
              Image.network(_picUrl,
                  height: 80.0,
                  // 橫向重復(fù)
                  repeat: ImageRepeat.repeatX,
                  // MediaQuery.of(context).size 獲取到的為上層容器的寬高
                  width: MediaQuery.of(context).size.width),
              // 通過設(shè)置混合模式,可以看到圖片展示的樣式已經(jīng)修改
              Image.asset(_assetAli,
                  width: 80.0, height: 80.0, color: Colors.green, colorBlendMode: BlendMode.colorDodge),
              // 會優(yōu)先加載指定的 asset 圖片庵寞,然后等網(wǎng)絡(luò)圖片讀取成功后加載網(wǎng)絡(luò)圖片狸相,會通過漸隱漸現(xiàn)方式展現(xiàn)
              // cover 方式按照較小的邊布滿,較大的給切割
              // contain 會按照最大的邊布滿捐川,較小的會被留白
              // fill 會把較大的一邊壓縮
              // fitHeight, fitWidth 分別按照長寬來布滿
              FadeInImage.assetNetwork(
                  placeholder: _assetAli, image: _picUrl, width: 120.0, height: 120.0, fit: BoxFit.cover),
              // Icon 相對屬性少了很多脓鹃,需要傳入一個 IconData 實(shí)例,flutter 提供了很多圖標(biāo)古沥,
              // 但是實(shí)際情況我們需要加入我們自己的圖標(biāo)瘸右,這邊再埋坑【坑3】
              // size 為圖標(biāo)顯示的大小,color 為圖標(biāo)的顏色岩齿,這邊通過 Theme 獲取主題色調(diào)
              Icon(Icons.android, size: 40.0, color: Theme.of(context).primaryColorDark)
            ],
          )),
        ));
  }
}

該部分代碼查看源碼 image_main.dart 文件

最后的效果如下:

Image 展示.png
Button

Flutter 提供了各種類型的 Button 幾乎是大同小異的太颤,這邊就抽取一些比較常用的展示下效果,常用的主要有 RaisedButton 盹沈、FlatButton龄章、IconButtonOutlineButton乞封、MaterialButton做裙、FloatActionButtonFloatingActionButton.extended

Button 都有一個 onPress 參數(shù)肃晚,是 VoidCallback 類型的參數(shù)锚贱,通過查看源碼可以知道 VoidCallback 是無參無返回值的一種類型參數(shù)。如果該參數(shù)傳入的值為 null 那么這個按鈕的就不可點(diǎn)擊狀態(tài)关串,無點(diǎn)擊效果拧廊,等會可以在例子中查看杂穷。還有就是 child 參數(shù),這里就是傳入你需要展示的內(nèi)容卦绣,比如 Text耐量、Icon 等等。別的參數(shù)基本可以通過參數(shù)名了解滤港,這邊不擴(kuò)展了(再看源碼我怕你們都不想繼續(xù)看下去了...)

Talk is cheap, show me the code

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        padding: const EdgeInsets.only(top: 10.0),
        child: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                print('This is a Rased Button can be clicked');
              },
              child: Text('Raised Enable'),
            ),
            RaisedButton(onPressed: null, child: Text('Raised Disable')),
            FlatButton(
              onPressed: () => print('This is a Flat Button can be clicker'),
              child: Text('Flat Enable'),
            ),
            FlatButton(onPressed: null, child: Text('Flat Disable')),
            IconButton(icon: Icon(Icons.android), onPressed: () {}),
            IconButton(icon: Icon(Icons.android), onPressed: null),
            MaterialButton(onPressed: () {}, child: Text('Material Enable')),
            MaterialButton(onPressed: null, child: Text('Material Disable')),
            OutlineButton(onPressed: () {}, child: Text('Outline Enable')),
            OutlineButton(onPressed: null, child: Text('Outline Enable')),
          ],
        )),
      ),
      floatingActionButton:
          FloatingActionButton.extended(onPressed: () {}, icon: Icon(Icons.android), label: Text('Android')),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}

該部分代碼查看源碼 button_main.dart 部分

最終的效果圖:

button 展示.png

這篇終于到末尾了廊蜒,最后留了 3 個坑等以后解決

最后代碼的地址還是要的:

  1. 文章中涉及的代碼:demos

  2. 基于郭神 cool weather 接口的一個項(xiàng)目,實(shí)現(xiàn) BLoC 模式溅漾,實(shí)現(xiàn)狀態(tài)管理:flutter_weather

  3. 一個課程(當(dāng)時買了想看下代碼規(guī)范的山叮,代碼更新會比較慢,雖然是跟著課上的一些寫代碼添履,但是還是做了自己的修改屁倔,很多地方看著不舒服,然后就改成自己的實(shí)現(xiàn)方式了):flutter_shop

如果對你有幫助的話暮胧,記得給個 Star锐借,先謝過,你的認(rèn)可就是支持我繼續(xù)寫下去的動力~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末往衷,一起剝皮案震驚了整個濱河市钞翔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌席舍,老刑警劉巖布轿,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異来颤,居然都是意外死亡汰扭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門福铅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萝毛,“玉大人,你說我怎么就攤上這事本讥∩河荆” “怎么了鲁冯?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵拷沸,是天一觀的道長。 經(jīng)常有香客問我薯演,道長撞芍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任跨扮,我火速辦了婚禮序无,結(jié)果婚禮上验毡,老公的妹妹穿的比我還像新娘。我一直安慰自己帝嗡,他們只是感情好晶通,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哟玷,像睡著了一般狮辽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巢寡,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天喉脖,我揣著相機(jī)與錄音,去河邊找鬼抑月。 笑死树叽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谦絮。 我是一名探鬼主播题诵,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼层皱!你這毒婦竟也來了仇轻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤奶甘,失蹤者是張志新(化名)和其女友劉穎篷店,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體臭家,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疲陕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了钉赁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹄殃。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖你踩,靈堂內(nèi)的尸體忽然破棺而出诅岩,到底是詐尸還是另有隱情,我是刑警寧澤带膜,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布吩谦,位于F島的核電站,受9級特大地震影響膝藕,放射性物質(zhì)發(fā)生泄漏式廷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一芭挽、第九天 我趴在偏房一處隱蔽的房頂上張望滑废。 院中可真熱鬧蝗肪,春花似錦、人聲如沸蠕趁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俺陋。三九已至逛绵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間倔韭,已是汗流浹背术浪。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寿酌,地道東北人胰苏。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像醇疼,于是被迫代替她去往敵國和親硕并。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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