Flutter中布局類Widget

前言

本文的目的是為了讓讀者掌握不同布局類Widget的布局特點(diǎn)傻盟,分享一些在實(shí)際使用過程遇到的一些問題戈钢,在《Flutter實(shí)戰(zhàn)》這本書中已經(jīng)講解的很詳細(xì)了,本文主要是對(duì)其內(nèi)容的濃縮及實(shí)際遇到的問題的補(bǔ)充。

什么是布局類Widget

布局類Widget就是指直接或間接繼承(包含)MultiChildRenderObjectWidget的Widget彪蓬,它們一般都會(huì)有一個(gè)children屬性用于接收子Widget。在Flutter中Element樹才是最終的繪制樹捺萌,Element樹是通過widget樹來創(chuàng)建的(通過Widget.createElement())档冬,widget其實(shí)就是Element的配置數(shù)據(jù)。它的最終布局桃纯、UI界面渲染都是通過RenderObject對(duì)象來實(shí)現(xiàn)的酷誓,這里的細(xì)節(jié)我就不詳細(xì)描述了,因?yàn)槲乙膊欢埂2贿^感興趣的小伙伴也可以看看本專欄的Flutter視圖的Layout與Paint這篇文章呛牲。

Flutter中主要有以下幾種布局類的Widget:

  • 線性布局Row和Column
  • 彈性布局Flex
  • 流式布局Wrap、Flow
  • 層疊布局Stack驮配、Positioned

本文Demo地址

線性布局Row和Column

線性布局其實(shí)是指沿水平或垂直方向排布子Widget娘扩,F(xiàn)lutter中通過Row來實(shí)現(xiàn)水平方向的子Widegt布局着茸,通過Column來實(shí)現(xiàn)垂直方向的子Widget布局。他們都繼承Flex琐旁,所以它們有很多相似的屬性涮阔。


Row

Column

在前端的Flex布局中,默認(rèn)存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)灰殴。主軸的開始位置(與邊框的交叉點(diǎn))叫做main start敬特,結(jié)束位置叫做main end;交叉軸的開始位置叫做cross start牺陶,結(jié)束位置叫做cross end伟阔。與Flutter中MainAxisAlignment和CrossAxisAlignment類似,分別代表主軸對(duì)齊和縱軸對(duì)齊掰伸。

源碼屬性解讀

  Row({
    .....
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    List<Widget> children = const <Widget>[],
  })

  Column({
    .....
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    List<Widget> children = const <Widget>[],
  }) 
  • textDirection:表示水平方向子widget的布局順序(是從左往右還是從右往左)皱炉,默認(rèn)為系統(tǒng)當(dāng)前Locale環(huán)境的文本方向(如中文、英語都是從左往右狮鸭,而阿拉伯語是從右往左)合搅。
  • 主軸方向: Row即為水平方向,Column為垂直方向
  • mainAxisAlignment 主軸方向歧蕉,對(duì)child起作用
    • center:將children放置在主軸的中心
    • start:將children放置在主軸的起點(diǎn)
    • end:將children放置在主軸的末尾
    • spaceAround:將主軸方向上的空白區(qū)域均分灾部,使children之間的空白區(qū)域相等,但是首尾child的靠邊間距為空白區(qū)域?yàn)?/2
    • spaceBetween:將主軸方向上的空白區(qū)域均分惯退,使children之間的空白區(qū)域相等赌髓,首尾child靠邊沒有間隙
    • spaceEvenly:將主軸方向上的空白區(qū)域均分,使得children之間的空白區(qū)域相等催跪,包括首尾child
  • mainAxisSize max表示盡可能占多的控件锁蠕,min會(huì)導(dǎo)致控件聚攏在一起
  • crossAxisAlignment 交叉軸方向,對(duì)child起作用
    • baseline:使children baseline對(duì)齊
    • center:children在交叉軸上居中展示
    • end:children在交叉軸上末尾展示
    • start:children在交叉軸上起點(diǎn)處展示
    • stretch:讓children填滿交叉軸方向
  • verticalDirection 叠荠,child的放置順序
    • VerticalDirection.down匿沛,在Row中就是從左邊到右邊,Column代表從頂部到底部
    • VerticalDirection.up榛鼎,相反

Row

示例代碼
ListView(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            Text("我是Row的子控件  "),
            Text("MainAxisAlignment.start")
          ],
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("我是Row的子控件  "),
            Text("MainAxisAlignment.center")
          ],
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            Text("我是Row的子控件  "),
            Text("MainAxisAlignment.end")
          ],
        ),
        Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          verticalDirection: VerticalDirection.up,
          children: <Widget>[
            Text(" Hello World ", style: TextStyle(fontSize: 30.0),),
            Text(" I am Jack "),
          ],
      ],
    )
代碼運(yùn)行效果
image.png

前3個(gè)Row很簡(jiǎn)單逃呼,只是設(shè)置了主軸方向的對(duì)齊方式;第四個(gè)Row測(cè)試的是縱軸的對(duì)齊方式者娱,由于兩個(gè)子Text字體不一樣抡笼,所以其高度也不同,我們指定了verticalDirection值為VerticalDirection.up黄鳍,即從低向頂排列推姻,而此時(shí)crossAxisAlignment值為CrossAxisAlignment.start表示底對(duì)齊。大家可以參考上面Row和Column的主側(cè)軸的示意圖框沟,看看布局是不是正確的藏古,還有很多種情況就不一一列舉了增炭。

Column

示例代碼
ListView(children: <Widget>[
      Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text("我是Colum的子控件"),
          Text("CrossAxisAlignment.start"),
        ],
      ),
      Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Text("我是Colum的子控件"),
          Text("CrossAxisAlignment.center"),
        ],
      ),
      Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: <Widget>[
          Text("我是Colum的子控件"),
          Text("CrossAxisAlignment.end"),
        ],
      ),
    ],)
代碼運(yùn)行效果
image.png

Column和Row差不多,只是布局方向不一樣而已拧晕,大家可以參考著看隙姿,這里就不再贅述了。

實(shí)際使用

由于篇幅有限厂捞,我就不詳細(xì)講解實(shí)際遇到的問題了输玷,只說現(xiàn)象和解決辦法:

  • 如果Row里面嵌套R(shí)ow,或者Column里面再嵌套Column靡馁,那么只有對(duì)最外面的Row或Column會(huì)占用盡可能大的空間欲鹏,里面Row或Column所占用的空間為實(shí)際大小,如果要讓里面的Colum或Row占滿外部Colum或Row臭墨,可以使用Expanded widget
  • 如果使用Column發(fā)現(xiàn)超范圍赔嚎,可用SingleChildScrollView包裹,scrollDirection屬性設(shè)置滑動(dòng)方向
  • 使用Column嵌套ListView/GridView的時(shí)候裙犹,會(huì)報(bào)異常信息【Viewports expand in the scrolling direction to fill their container...】尽狠,這種情況flutter已給出解決辦法衔憨,將ListView/GridView的 shrinkWrap屬性設(shè)為true
  • 有的時(shí)候修改Row/Column的verticalDirection會(huì)得到很好的效果叶圃,比如需要頁面在底部需要幾個(gè)按鍵,也可以用Stack來布局践图,但是相對(duì)麻煩掺冠,而且有時(shí)還需要知道控件的大小,沒有verticalDirection方便

彈性布局

彈性布局是一種允許子widget按照一定比例來分配父容器空間的布局方式码党,如果你知道了它的主軸方向德崭,那就可以用Row或Column了,一般情況下揖盘,可以用Flex的地方都可以用Row或者Column一起使用眉厨,通常配合Expanded Widget來使用,同樣Expanded也不能脫離Flex單獨(dú)創(chuàng)建兽狭。

Expanded

Expanded繼承自Flexible憾股,F(xiàn)lexible是一個(gè)控制Row、Column箕慧、Flex等子組件如何布局的組件服球,它可以按比例“擴(kuò)伸”Row、Column和Flex子widget所占用的空間颠焦。

const Expanded({
  int flex = 1, 
  @required Widget child,
})

flex為彈性系數(shù)斩熊,如果為0或null,則child是沒有彈性的伐庭,即不會(huì)被擴(kuò)伸占用的空間粉渠。如果大于0分冈,所有的Expanded按照其flex的比例來分割主軸的全部空閑空間。

示例代碼
 Row(children: <Widget>[
        RaisedButton(
          onPressed: () {
            print('點(diǎn)擊紅色按鈕事件');
          },
          color: Colors.red,
          child: Text('紅色按鈕'),
        ),
        Expanded(
          flex: 1,
          child: RaisedButton(
            onPressed: () {
              print('點(diǎn)擊黃色按鈕事件');
            },
            color: Colors.yellow,
            child: Text('黃色按鈕'),
          ),
        ),
        RaisedButton(
          onPressed: () {
            print('點(diǎn)擊粉色按鈕事件');
          },
          color: Colors.green,
          child: Text('綠色按鈕'),
        ),
      ])
代碼運(yùn)行效果
image.png
Flexible和 Expanded的區(qū)別
  • Flexible組件必須是Row霸株、Column丈秩、Flex等組件的后裔,并且從Flexible到它封裝的Row淳衙、Column蘑秽、Flex的路徑必須只包括StatelessWidgets或StatefulWidgets組件(不能是其他類型的組件,像RenderObjectWidgets)
  • Row箫攀、Column肠牲、Flex會(huì)被Expanded撐開,充滿主軸可用空間靴跛,而Flexible不強(qiáng)制子組件填充可用空間缀雳,這是因?yàn)閒it屬性的值不同,該屬性在Expanded中為FlexFit.tight梢睛,F(xiàn)lexible為FlexFit.loose肥印,區(qū)別在于tight表示強(qiáng)制使子控件填充剩余可用空間,loose表示最多填滿其在父控件所設(shè)置的比例绝葡,所以loose默認(rèn)即為控件的大小

流式布局

流式布局(Liquid)的特點(diǎn)(也叫"Fluid") 是頁面元素的寬度按照屏幕分辨率進(jìn)行適配調(diào)整深碱,但整體布局不變。柵欄系統(tǒng)(網(wǎng)格系統(tǒng))藏畅,用戶標(biāo)簽等敷硅。在Flutter中主要有Wrap和Flow兩種Widget實(shí)現(xiàn)。

Wrap

在介紹Row和Colum時(shí)愉阎,如果子widget超出屏幕范圍绞蹦,則會(huì)報(bào)溢出錯(cuò)誤,在Flutter中通過Wrap和Flow來支持流式布局榜旦,溢出部分則會(huì)自動(dòng)折行幽七。

源碼屬性解讀
Wrap({
  ...
  this.direction = Axis.horizontal,
  this.alignment = WrapAlignment.start,
  this.spacing = 0.0,
  this.runAlignment = WrapAlignment.start,
  this.runSpacing = 0.0,
  this.crossAxisAlignment = WrapCrossAlignment.start,
  this.textDirection,
  this.verticalDirection = VerticalDirection.down,
  List<Widget> children = const <Widget>[],
})

上述有很多屬性和Row的相同,其意義其實(shí)也是相同的溅呢,這里我就不一一介紹了澡屡,主要介紹下不同的屬性:

  • spacing:主軸方向子widget的間距
  • runSpacing:縱軸方向的間距
  • runAlignment:縱軸方向的對(duì)齊方式
示例代碼
Wrap(
   spacing: 10.0,
   direction: Axis.horizontal,
   alignment: WrapAlignment.start,
   children: <Widget>[
     _card('關(guān)注'),
     _card('推薦'),
     _card('新時(shí)代'),
     _card('小視頻'),
     _card('黨媒推薦'),
     _card('中國新唱將'),
     _card('歷史'),
     _card('視頻'),
     _card('游戲'),
     _card('頭條號(hào)'),
     _card('數(shù)碼'),
   ],
 )

  Widget _card(String title) {
    return Card(child: Text(title),);
  }
}
運(yùn)行效果
image.png
小結(jié)
  • 使用Wrap可以很輕松的實(shí)現(xiàn)流式布局效果
  • Wrap支持設(shè)置流式布局是縱向顯示或者是橫向顯示
  • 可以使用alignment屬性來控制widgets的布局方式

Flow

我們一般很少會(huì)使用Flow,因?yàn)槠溥^于復(fù)雜藕届,需要自己實(shí)現(xiàn)子widget的位置轉(zhuǎn)換挪蹭,在很多場(chǎng)景下首先要考慮的是Wrap是否滿足需求。Flow主要用于一些需要自定義布局策略或性能要求較高(如動(dòng)畫中)的場(chǎng)景休偶。Flow有如下優(yōu)點(diǎn):

  • 性能好梁厉;Flow是一個(gè)對(duì)child尺寸以及位置調(diào)整非常高效的控件,F(xiàn)low用轉(zhuǎn)換矩陣(transformation matrices)在對(duì)child進(jìn)行位置調(diào)整的時(shí)候進(jìn)行了優(yōu)化:在Flow定位過后,如果child的尺寸或者位置發(fā)生了變化词顾,在FlowDelegate中的paintChildren()方法中調(diào)用context.paintChild 進(jìn)行重繪八秃,而context.paintChild在重繪時(shí)使用了轉(zhuǎn)換矩陣(transformation matrices),并沒有實(shí)際調(diào)整Widget位置肉盹。
  • 靈活昔驱;由于我們需要自己實(shí)現(xiàn)FlowDelegate的paintChildren()方法,所以我們需要自己計(jì)算每一個(gè)widget的位置上忍,因此骤肛,可以自定義布局策略。
    缺點(diǎn):
  • 使用復(fù)雜.
  • 不能自適應(yīng)子widget大小,必須通過指定父容器大小或?qū)崿F(xiàn)TestFlowDelegate的getSize返回固定大小。
示例代碼

我們對(duì)六個(gè)色塊進(jìn)行自定義流式布局:

Flow(
  delegate: TestFlowDelegate(margin: EdgeInsets.all(10.0)),
  children: <Widget>[
    new Container(width: 80.0, height:80.0, color: Colors.red,),
    new Container(width: 80.0, height:80.0, color: Colors.green,),
    new Container(width: 80.0, height:80.0, color: Colors.blue,),
    new Container(width: 80.0, height:80.0,  color: Colors.yellow,),
    new Container(width: 80.0, height:80.0, color: Colors.brown,),
    new Container(width: 80.0, height:80.0,  color: Colors.purple,),
  ],
)

實(shí)現(xiàn)TestFlowDelegate:

class TestFlowDelegate extends FlowDelegate {
  EdgeInsets margin = EdgeInsets.zero;
  TestFlowDelegate({this.margin});
  @override
  void paintChildren(FlowPaintingContext context) {
    var x = margin.left;
    var y = margin.top;
    //計(jì)算每一個(gè)子widget的位置  
    for (int i = 0; i < context.childCount; i++) {
      var w = context.getChildSize(i).width + x + margin.right;
      if (w < context.size.width) {
        context.paintChild(i,
            transform: new Matrix4.translationValues(
                x, y, 0.0));
        x = w + margin.left;
      } else {
        x = margin.left;
        y += context.getChildSize(i).height + margin.top + margin.bottom;
        //繪制子widget(有優(yōu)化)  
        context.paintChild(i,
            transform: new Matrix4.translationValues(
                x, y, 0.0));
        x += context.getChildSize(i).width + margin.left + margin.right;
      }
    }
  }

  getSize(BoxConstraints constraints){
    //指定Flow的大小  
    return Size(double.infinity,200.0);
  }

  @override
  bool shouldRepaint(FlowDelegate oldDelegate) {
    return oldDelegate != this;
  }
}
運(yùn)行效果
image.png

可以看到我們主要的任務(wù)就是實(shí)現(xiàn)paintChildren泳叠,它的主要任務(wù)是確定每個(gè)子widget位置。由于Flow不能自適應(yīng)子widget的大小咸产,我們通過在getSize返回一個(gè)固定大小來指定Flow的大小,實(shí)現(xiàn)起來還是比較麻煩的。

小結(jié)
  • 參數(shù)簡(jiǎn)單,不過需要自己定義delegate
  • delegate一般是為了實(shí)現(xiàn)child的繪制絮蒿,就是位置的擺放,不同情況需要定義不同的delegate
  • 不同的delegate一般會(huì)提供實(shí)現(xiàn)的幾個(gè)方法:
    • getConstraintsForChild: 設(shè)置每個(gè)child的布局約束條件叁鉴,會(huì)覆蓋已有的方式
    • getSize:設(shè)置控件的尺寸
    • shouldRelayout:表示是否需要重新布局
  • 盡可能的用Wrap土涝,畢竟簡(jiǎn)單

層疊布局

層疊布局和Web中的絕對(duì)定位、Android中的Frame布局是相似的亲茅,子widget可以根據(jù)到父容器四個(gè)角的位置來確定本身的位置回铛。絕對(duì)定位允許子widget堆疊(按照代碼中聲明的順序)狗准。Flutter中使用Stack和Positioned來實(shí)現(xiàn)絕對(duì)定位克锣,Stack允許子widget堆疊,而Positioned可以給子widget定位(根據(jù)Stack的四個(gè)角)腔长。

Stack

Stack({
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})
  • alignment:此參數(shù)決定如何去對(duì)齊沒有定位(沒有使用Positioned)或部分定位的子widget袭祟。所謂部分定位,在這里特指沒有在某一個(gè)軸上定位:left捞附、right為橫軸巾乳,top、bottom為縱軸鸟召,只要包含某個(gè)軸上的一個(gè)定位屬性就算在該軸上有定位胆绊。
  • textDirection:和Row、Wrap的textDirection功能一樣欧募,都用于決定alignment對(duì)齊的參考系即:textDirection的值為TextDirection.ltr压状,則alignment的start代表左,end代表右;textDirection的值為TextDirection.rtl种冬,則alignment的start代表右镣丑,end代表左。
  • fit:此參數(shù)用于決定沒有定位的子widget如何去適應(yīng)Stack的大小娱两。StackFit.loose表示使用子widget的大小莺匠,StackFit.expand表示擴(kuò)伸到Stack的大小。
  • overflow:此屬性決定如何顯示超出Stack顯示空間的子widget十兢,值為Overflow.clip時(shí)趣竣,超出部分會(huì)被剪裁(隱藏),值為Overflow.visible 時(shí)則不會(huì)旱物。
下面是我用Stack實(shí)現(xiàn)的一個(gè)簡(jiǎn)易的loading
class Loading extends StatelessWidget {
  /// ProgressIndicator的padding期贫,決定loading的大小
  final EdgeInsets padding = EdgeInsets.all(30.0);

  /// 文字頂部距菊花的底部的距離
  final double margin = 10.0;

  /// 圓角
  final double cornerRadius = 10.0;

  final Widget _child;
  final bool _isLoading;
  final double opacity;
  final Color color;
  final String text;

  Loading({
    Key key,
    @required child,
    @required isLoading,
    this.text,
    this.opacity = 0.3,
    this.color = Colors.grey,
  })  : assert(child != null),
        assert(isLoading != null),
        _child = child,
        _isLoading = isLoading,
        super(key: key);

  @override
  Widget build(BuildContext context) {
    List<Widget> widgetList = List<Widget>();
    widgetList.add(_child);
    if (_isLoading) {
      final loading = [
        Opacity(
          opacity: opacity,
          child: ModalBarrier(dismissible: false, color: color),
        ),
        _buildProgressIndicator()
      ];
      widgetList.addAll(loading);
    }
    return Stack(
      children: widgetList,
    );
  }

  Widget _buildProgressIndicator() {
    return Center(
      child: Container(
        padding: padding,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            CupertinoActivityIndicator(),
            Padding(
                padding: EdgeInsets.only(top: margin),
                child: Text(text ?? '加載中...')),
          ],
        ),
        decoration: BoxDecoration(
            borderRadius: BorderRadius.all(Radius.circular(cornerRadius)),
            color: Colors.white),
      ),
    );
  }
}
顯示效果
image.png

本控件使用Stack封裝,你傳入的主視圖在最下面一層异袄,背景層在中間通砍,最上面一層為菊花和文字loading,用isLoading控制顯示

Positioned

const Positioned({
  Key key,
  this.left, 
  this.top,
  this.right,
  this.bottom,
  this.width,
  this.height,
  @required Widget child,
})

left烤蜕、top 封孙、right、 bottom分別代表離Stack左讽营、上虎忌、右、底四邊的距離橱鹏。width和height用于指定定位元素的寬度和高度膜蠢,注意,此處的width莉兰、height 和其它地方的意義稍微有點(diǎn)區(qū)別挑围,此處用于配合left、top 糖荒、right杉辙、 bottom來定位widget,舉個(gè)例子捶朵,在水平方向時(shí)蜘矢,你只能指定left、right综看、width三個(gè)屬性中的兩個(gè)品腹,如指定left和width后,right會(huì)自動(dòng)算出(left+width)红碑,如果同時(shí)指定三個(gè)屬性則會(huì)報(bào)錯(cuò)舞吭,垂直方向同理。

示例代碼
//通過ConstrainedBox來確保Stack占滿屏幕
ConstrainedBox(
  constraints: BoxConstraints.expand(),
  child: Stack(
    alignment:Alignment.center , //指定未定位或部分定位widget的對(duì)齊方式
    children: <Widget>[
      Container(child: Text("Hello world",style: TextStyle(color: Colors.white)),
        color: Colors.red,
      ),
      Positioned(
        left: 18.0,
        child: Text("I am Jack"),
      ),
      Positioned(
        top: 18.0,
        child: Text("Your friend"),
      )        
    ],
  ),
);
運(yùn)行效果:
image.png

由于第一個(gè)子widget Text("Hello world")沒有指定定位,并且alignment值為Alignment.center镣典,所以兔毙,它會(huì)居中顯示。第二個(gè)子widget Text("I am Jack")只指定了水平方向的定位(left)兄春,所以屬于部分定位澎剥,即垂直方向上沒有定位,那么它在垂直方向?qū)R方式則會(huì)按照alignment指定的對(duì)齊方式對(duì)齊赶舆,即垂直方向居中哑姚。對(duì)于第三個(gè)子widget Text("Your friend"),和第二個(gè)Text原理一樣芜茵,只不過是水平方向沒有定位叙量,則水平方向居中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末九串,一起剝皮案震驚了整個(gè)濱河市绞佩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌猪钮,老刑警劉巖品山,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異烤低,居然都是意外死亡肘交,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門扑馁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涯呻,“玉大人,你說我怎么就攤上這事腻要「垂蓿” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵闯第,是天一觀的道長市栗。 經(jīng)常有香客問我,道長咳短,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任蛛淋,我火速辦了婚禮咙好,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘褐荷。我一直安慰自己勾效,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著层宫,像睡著了一般杨伙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上萌腿,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天限匣,我揣著相機(jī)與錄音,去河邊找鬼毁菱。 笑死米死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贮庞。 我是一名探鬼主播峦筒,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼窗慎!你這毒婦竟也來了物喷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤遮斥,失蹤者是張志新(化名)和其女友劉穎脯丝,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伏伐,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宠进,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了藐翎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片材蹬。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吝镣,靈堂內(nèi)的尸體忽然破棺而出堤器,到底是詐尸還是另有隱情,我是刑警寧澤末贾,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布闸溃,位于F島的核電站,受9級(jí)特大地震影響拱撵,放射性物質(zhì)發(fā)生泄漏辉川。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一拴测、第九天 我趴在偏房一處隱蔽的房頂上張望乓旗。 院中可真熱鬧,春花似錦集索、人聲如沸屿愚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妆距。三九已至穷遂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娱据,已是汗流浹背蚪黑。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吸耿,地道東北人祠锣。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像咽安,于是被迫代替她去往敵國和親伴网。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • 1.Row 線性布局妆棒,將children排成一行澡腾,主軸為水平方向,交叉軸為垂直方向糕珊。 textDirection:...
    hxljy閱讀 786評(píng)論 0 5
  • 轉(zhuǎn)自 Q吹個(gè)大氣球Q 本文主要介紹Flutter布局中的Row红选、Column控件澜公,詳細(xì)介紹了其布局行為以及使用場(chǎng)景...
    chilim閱讀 2,756評(píng)論 0 1
  • 我們,不再年輕了喇肋, 黑發(fā)中也有白發(fā)了坟乾, 身體開始發(fā)福了, 以前喜歡大魚大肉蝶防, 現(xiàn)在特別喜歡吃素甚侣。 我們,不再年輕了...
    fbf7511de1a6閱讀 142評(píng)論 0 1
  • 一间学、學(xué)習(xí)體會(huì)這一節(jié)的學(xué)習(xí)難度沒有什么太大殷费,只是列表類的數(shù)據(jù)類型有,列表低葫,元祖详羡,字典,集合氮采,他們有很多相同與不同殷绍,所...
    大胡子歌歌閱讀 355評(píng)論 0 0
  • 思維決定行為,行為決定習(xí)慣鹊漠,習(xí)慣決定性格主到,性格決定命運(yùn)——思維決定命運(yùn) 好早就在圈媽那里聽說了“拆書幫”,但直到現(xiàn)...
    皓媽田晶閱讀 259評(píng)論 0 0