Flutter跨平臺移動端開發(fā)丨Padding、ConstrainedBox、SizeBox、DecoratedBox、Transform、Container、Scaffold、TabBar

目錄

  1. Padding(間距)
  2. ConstrainedBox(約束盒)
  3. SizeBox(固定盒)
  4. UnconstrainedBox(無約束盒)
  5. DecoratedBox(裝飾盒)
  6. Container(組合容器)
  7. Scaffold Widget and TabBar Widget(腳手架及切換組件)

Padding(間距)

使用 padding 標(biāo)簽可以給子 widget 添加間距

  const Padding({
    Key key,
    @required this.padding,
    Widget child,
  }) : assert(padding != null),
       super(key: key, child: child);
  • all:指定四個方向使用同一間距
  • fromLTRB:四個方向間距分別制定
  • only:指定單一具體方向間距
  • symmetric:設(shè)置對稱方向間距(vertical = top+bottom,horizontal = left+right)
/**
 * @des Padding Widget
 * @author liyongli 20190424
 * */
class PaddingWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _PaddingState();

}

/**
 * @des Padding Widget State
 * @author liyongli 20190424
 * */
class _PaddingState extends State<PaddingWidget>{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("Padding Widget"),
          ),

          body: Column(
                children: <Widget>[

                  Padding(
                    padding: EdgeInsets.all(20.0),
                    child: RaisedButton(
                      child: Text("四個方向間距統(tǒng)一"),
                      color: Colors.blue ,
                      textColor: Colors.white,
                      onPressed: _BtnClick,
                    ),
                  ),

                  Padding(
                    padding: EdgeInsets.fromLTRB(0.0,20.0,40.0,20.0),
                    child: RaisedButton(
                      child: Text("分別指定四個方向"),
                      color: Colors.blue ,
                      textColor: Colors.white,
                      onPressed: _BtnClick,
                    ),
                  ),

                  Padding(
                    padding: EdgeInsets.only(left:40.0),
                    child: RaisedButton(
                      child: Text("單一方向添加邊距"),
                      color: Colors.blue ,
                      textColor: Colors.white,
                      onPressed: _BtnClick,
                    ),
                  ),

                  Padding(
                    padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 20.0),
                    child: RaisedButton(
                      child: Text("對稱方向添加邊距"),
                      color: Colors.blue ,
                      textColor: Colors.white,
                      onPressed: _BtnClick,
                    ),
                  ),
                ],
              )
      ),
    );
  }

  // 按鈕點擊監(jiān)聽
  void _BtnClick(){
    print("不設(shè)置點擊事件按鈕會是灰色的!");
  }

}

ConstrainedBox(約束盒)

constrainedBox 可以給子 widget 添加更多約束條件。與 sizedBox 同通過 renderConstrainedBox 繪制

  const BoxConstraints({
    this.minWidth = 0.0,
    this.maxWidth = double.infinity,
    this.minHeight = 0.0,
    this.maxHeight = double.infinity
  });
  • minWidth:子 widget 最小寬度
  • maxWidth:子 widget 最大寬度
  • minHeight:子 widget 最小高度
  • maxHeight:子 widget 最大高度
@override
RenderConstrainedBox createRenderObject(BuildContext context) {
  return new RenderConstrainedBox(
    additionalConstraints: ...,
  );
}
/**
 * @des ConstrainedBox Widget
 * @author liyongli 20190424
 * */
class ConstrainedBoxWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _ConstrainedBoxState();

}

/**
 * @des ConstrainedBox Widget State
 * @author liyongli 20190424
 * */
class _ConstrainedBoxState extends State<ConstrainedBoxWidget>{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("ConstrainedBox Widget"),
          ),

          body: ConstrainedBox(
            constraints: BoxConstraints(
              minHeight: 50.0,
              minWidth: double.infinity
            ),
            child: RaisedButton(
                      child: Text("A"),
                      color: Colors.blue ,
                      textColor: Colors.white,
                      onPressed: _BtnClick,
            )
          ),
      )
    );
  }

  // 按鈕點擊監(jiān)聽
  void _BtnClick(){
    print("不設(shè)置點擊事件按鈕會是灰色的!");
  }

}

SizeBox(固定盒)

sizedBox 可以給子 widget 指定寬高。與 constrainedBox 同通過 renderConstrainedBox 繪制

@override
RenderConstrainedBox createRenderObject(BuildContext context) {
  return new RenderConstrainedBox(
    additionalConstraints: ...,
  );
}
/**
 * @des SizedBox Widget
 * @author liyongli 20190424
 * */
class SizedBoxWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _SizedBoxState();

}

/**
 * @des SizedBox Widget State
 * @author liyongli 20190424
 * */
class _SizedBoxState extends State<SizedBoxWidget>{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("SizedBox Widget"),
          ),

          body: SizedBox(
            width: double.infinity,
            height: 80.0,
            child: RaisedButton(
                      child: Text("A"),
                      color: Colors.blue ,
                      textColor: Colors.white,
                      onPressed: _BtnClick,
            )
          ),
      )
    );
  }

  // 按鈕點擊監(jiān)聽
  void _BtnClick(){
    print("不設(shè)置點擊事件按鈕會是灰色的!");
  }

}

UnconstrainedBox(無約束盒)

unconstrainedBox 允許子 widget 按照自有屬性繪制,可用作去除父 widget 限制

/**
 * @des UnconstrainedBox Widget
 * @author liyongli 20190424
 * */
class UnconstrainedBoxWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _UnconstrainedBoxState();

}

/**
 * @des UnconstrainedBox Widget State
 * @author liyongli 20190424
 * */
class _UnconstrainedBoxState extends State<UnconstrainedBoxWidget>{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("UnconstrainedBox Widget"),
          ),

          body: SizedBox(
            width: double.infinity,
            height: 80.0,
            child: UnconstrainedBox(
              child: RaisedButton(
                child: Text("A"),
                color: Colors.blue ,
                textColor: Colors.white,
                onPressed: _BtnClick,
              ),
            )
          ),
      )
    );
  }

  // 按鈕點擊監(jiān)聽
  void _BtnClick(){
    print("不設(shè)置點擊事件按鈕會是灰色的!");
  }

}

雖然從效果來看,父 widget 的限制沒有起作用,但是實際上它只是沒有影響子 widget 的大小,但還是占有了響應(yīng)的空間


DecoratedBox(裝飾盒)

decoratedBox 可以給子 widget 繪制前、后增添一個裝飾

  const DecoratedBox({
    Key key,
    @required this.decoration,
    this.position = DecorationPosition.background,
    Widget child
  }) : assert(decoration != null),
       assert(position != null),
       super(key: key, child: child);
  • decoration:即將繪制的裝飾
  • position:繪制時間。background = 在子 widget 之后繪制,foreground = 在子 widget 之前繪制
  • child:子 widget
/**
 * @des DecoratedBox Widget
 * @author liyongli 20190425
 * */
class DecoratedBoxWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _DecoratedBoxState();

}

/**
 * @des DecoratedBox Widget State
 * @author liyongli 20190425
 * */
class _DecoratedBoxState extends State<DecoratedBoxWidget>{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("DecoratedBox Widget"),
          ),

          body: DecoratedBox(

            // 裝飾
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(15.0),
              gradient: LinearGradient(colors: [Colors.blue,Colors.purpleAccent]),
              boxShadow: [
                BoxShadow(
                  color: Colors.blue,
                  offset: Offset(5.0, 5.0),
                  blurRadius: 20.0
                )
              ]
            ),

            // 主體
            child: Padding(
              padding: EdgeInsets.symmetric(vertical: 10.0,horizontal: 40.0),
              child: Text("flutter", style: TextStyle(color: Colors.white ),),
            ),
          ),
      )
    );
  }
}

Container(組合容器)

container 是各種我們已知的 widget 的組合,使用它可以實現(xiàn)裝飾、變換、限制等各種效果

  Container({
    Key key,
    this.alignment,
    this.padding,
    Color color,
    Decoration decoration,
    this.foregroundDecoration,
    double width,
    double height,
    BoxConstraints constraints,
    this.margin,
    this.transform,
    this.child,
  }) : assert(margin == null || margin.isNonNegative),
       assert(padding == null || padding.isNonNegative),
       assert(decoration == null || decoration.debugAssertIsValid()),
       assert(constraints == null || constraints.debugAssertIsValid()),
       assert(color == null || decoration == null,
         'Cannot provide both a color and a decoration\n'
         'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'
       ),
       decoration = decoration ?? (color != null ? BoxDecoration(color: color) : null),
       constraints =
        (width != null || height != null)
          ? constraints?.tighten(width: width, height: height)
            ?? BoxConstraints.tightFor(width: width, height: height)
          : constraints,
       super(key: key);
  • width、height:當(dāng)一級標(biāo)簽與 constraints 中同時包含 width、height 時,一級標(biāo)簽優(yōu)先
/**
 * @des Container Widget
 * @author liyongli 20190425
 * */
class ContainerWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _ContainerState();

}

/**
 * @des Container Widget State
 * @author liyongli 20190425
 * */
class _ContainerState extends State<ContainerWidget>{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("Container Widget"),
          ),

          body: Container(
            margin: EdgeInsets.only(left:70.0), //容器外間距
            constraints: BoxConstraints.tightFor(width: 200.0, height: 150.0), //卡片大小

            // 裝飾
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15.0),
                gradient: LinearGradient(colors: [Colors.blue,Colors.purpleAccent]),
                boxShadow: [
                  BoxShadow(
                      color: Colors.blue,
                      offset: Offset(5.0, 5.0),
                      blurRadius: 20.0
                  )
                ]
            ),
            transform: Matrix4.rotationZ(0.2), //卡片傾斜變換
            alignment: Alignment.center, //卡片內(nèi)文字居中
            child: Text("flutter", style: TextStyle(color: Colors.white ),),
          )
      )
    );
  }
}

Scaffold Widget and TabBar Widget(腳手架及切換組件)

scaffold 是 Materrial 庫中提供的一個腳手架,可以幫助開發(fā)者更快的完成功能頁的開發(fā)

  const Scaffold({
    Key key,
    this.appBar,
    this.body,
    this.floatingActionButton,
    this.floatingActionButtonLocation,
    this.floatingActionButtonAnimator,
    this.persistentFooterButtons,
    this.drawer,
    this.endDrawer,
    this.bottomNavigationBar,
    this.bottomSheet,
    this.backgroundColor,
    this.resizeToAvoidBottomPadding,
    this.resizeToAvoidBottomInset,
    this.primary = true,
    this.drawerDragStartBehavior = DragStartBehavior.down,
  }) : assert(primary != null),
       assert(drawerDragStartBehavior != null),
       super(key: key);
  • key:當(dāng)前元素的唯一標(biāo)識符(類似于 Android 中的 id)
  • appBar:頂部導(dǎo)航欄
  • body:主體部分
  • floatingActionButton:懸浮按鈕
  • drawer:抽屜部件
  • bottomNavigationBar:底部導(dǎo)航欄

模擬商品詳情頁骨架


/**
 * @des Scaffold Widget
 * @author liyongli 20190426
 * */
class ScaffoldWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _ScaffoldState();

}

/**
 * @des Scaffold Widget State
 * @author liyongli 20190426
 * */
class _ScaffoldState extends State<ScaffoldWidget>{

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      
      // 導(dǎo)航欄
      appBar: AppBar(        title: Text("Detail"),
        centerTitle: true,
        elevation: 3.0,
        leading: Builder(builder: (context){
          return IconButton(
            iconSize: 20.0,
            icon: Icon(Icons.arrow_back_ios, color: Colors.white,),
            onPressed: _finishBtn,
          );
        }),

        actions: <Widget>[
          IconButton(
            iconSize: 20.0,
            icon: Icon(Icons.favorite_border, color: Colors.white,),
            onPressed: _collectionBtn,
          ),
          IconButton(
            iconSize: 20.0,
            icon: Icon(Icons.share, color: Colors.white,),
            onPressed: _moreBtn,
          ),
        ],
      ),
      
      // 懸浮按鈕
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.shopping_cart),
        onPressed: _shoppingBtn,),
      
    );
  }


  // finish
  void _finishBtn(){
    print("finish");
  }

  // shared
  void _collectionBtn(){
    print("shared");
  }
  
  // float
  void _moreBtn(){
    print("shared");
  }

  // shopping
  void _shoppingBtn(){
    print("shared");
  }
 
}

模擬新聞類APP骨架

/**
 * @des Scaffold and TabBar Widget
 * @author liyongli 20190426
 * */
class ScaffoldAndTabBarWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _ScaffoldAndTabBarState();

}

/**
 * @des Scaffold and TabBar Widget State
 * @author liyongli 20190426
 * */
class _ScaffoldAndTabBarState extends State<ScaffoldAndTabBarWidget>
    with SingleTickerProviderStateMixin {

  TabController _tabController;
  List tabs = ["熱點","綜合","科技","教育","財經(jīng)"];
  int _selectedIndex = 0;

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


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 導(dǎo)航欄
      appBar: AppBar(
        title: Text("News Home", style: TextStyle(fontSize: 16.0),),
        centerTitle: true,
        elevation: 3.0,
        leading: Builder(builder: (context){
          return IconButton(
            iconSize: 20.0,
            icon: Icon(Icons.person, color: Colors.white,),
            onPressed: _finishBtn,
          );
        }),

        actions: <Widget>[
          IconButton(
            iconSize: 20.0,
            icon: Icon(Icons.message, color: Colors.white,),
            onPressed: _moreBtn,
          ),
        ],

        bottom: TabBar(   //生成Tab菜單
            controller: _tabController,
            tabs: tabs.map((e) => Tab(text: e)).toList()
        ),
      ),

      bottomNavigationBar: BottomNavigationBar( // 底部導(dǎo)航
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
          BottomNavigationBarItem(icon: Icon(Icons.message), title: Text('Message')),
          BottomNavigationBarItem(icon: Icon(Icons.person), title: Text('personal')),
        ],
        currentIndex: _selectedIndex,
        fixedColor: Colors.blue,
        onTap: _onItemTapped,
      ),

      body: TabBarView(
        controller: _tabController,
        children: tabs.map((e) { //創(chuàng)建3個Tab頁
          return Container(
            alignment: Alignment.center,
            child: Text(e, textScaleFactor: 5),
          );
        }).toList(),
      ),
    );
  }

  // finish
  void _finishBtn(){
    print("finish");
  }

  // shared
  void _collectionBtn(){
    print("shared");
  }

  // float
  void _moreBtn(){
    print("shared");
  }

  // shopping
  void _shoppingBtn(){
    print("shared");
  }

  void _onItemTapped(int index) {

  }
}

本篇到此完結(jié),更多 Flutter 跨平臺移動端開發(fā) 原創(chuàng)內(nèi)容持續(xù)更新中~

期待您 關(guān)注 / 點贊 / 收藏 向著 大前端工程師 晉級!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容