Flutter Widget2

widget使用合集

1.Stack 層疊組件 Stack 與 Align Stack 與 Positioned 實現(xiàn)定位布局
2.AspectRatio 根據(jù)設置調(diào)整子元素 child 的寬高比
3.Card 卡片組件
4.Wrap 實現(xiàn)瀑布流(橫向 或者 縱向)
5.自定義有狀態(tài)組件 StatefulWidget
6.BottomNavigationBar 實現(xiàn)底部導航欄多頁面
7.自定義頂部導航按鈕 圖標您炉、顏色 以及 TabBar 定義頂部 Tab 切換
8.FlutterDrawer 側(cè)邊欄 抽屜樣式
9.Flutter 按鈕組件合集
10.表單組件 TextField赚爵,Radio,CheckBox

Stack 層疊組件 Stack 與 Align Stack 與 Positioned 實現(xiàn)定位布局

stack 有點類似Android的FrameLayout冀膝,幀布局,配合Align或者Positioned來定位容器內(nèi)的組件位置

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 300,
      height: 300,
      color: Colors.redAccent,
      child: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          Align(
            alignment: Alignment(-1, -1), //左上
            child: Icon(
              Icons.camera,
              size: 32,
              color: Colors.yellowAccent,
            ),
          ),
          Align(
            alignment: Alignment(0, 0), //中間
            child: Icon(
              Icons.supervised_user_circle,
              size: 32,
              color: Colors.blue,
            ),
          ),
          Align(
            alignment: Alignment(1, 1), //右下
            child: Icon(
              Icons.search,
              size: 32,
              color: Colors.white,
            ),
          ),
        ],
      ),
    );
  }
}

//配合positioned使用
 children: <Widget>[
          Positioned(
            left: 10,
            top: 10,
            child: Icon(
              Icons.camera,
              size: 32,
              color: Colors.yellowAccent,
            ),
          ),
          Positioned(
            right: 10,
            top: 10,
            child: Icon(
              Icons.supervised_user_circle,
              size: 32,
              color: Colors.blue,
            ),
          ),
          Positioned(
            bottom: 0,
            right: 0,
            child: Icon(
              Icons.search,
              size: 32,
              color: Colors.white,
            ),
          ),
        ],

33.png

positioned配合使用效果
44.png

層疊布局 小案例

class HomeContent extends StatelessWidget {
  Widget _getData(BuildContext context, int index) {
    return Container(
      margin: EdgeInsets.only(top: 10),
      height: 200,
      child: Stack(
        alignment: Alignment.bottomCenter,
        fit: StackFit.passthrough,
        children: <Widget>[
          Align(
            child: Image.network(
              listData[index]["imageUrl"],
              width: double.infinity,
              fit: BoxFit.fitWidth,
            ),
          ),
          Positioned(
            bottom: 10,
            child: Text(listData[index]["title"]),
          )
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: ListView.builder(
        itemBuilder: _getData,
        itemCount: listData.length,
      ),
    );
  }
}
55.png

AspectRatio 根據(jù)設置調(diào)整子元素 child 的寬高比

AspectRation 的子元素 寬度 占據(jù) 父組件,高度根據(jù)寬高比而定论笔,aspectRatio設置寬高比 比如16/9

 @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.all(10),
      color: Colors.pinkAccent,
      child: AspectRatio(
        aspectRatio: 3 / 1,
        child: Container(
          color: Colors.blue,
        ),
      ),
    );
  }

Card 組件

Card 是卡片組件塊狂魔,內(nèi)容可以由大多數(shù)類型的 Widget 構(gòu)成最楷,Card 具有圓角和陰影籽孙,這讓它 看起來有立體感犯建。

class HomeContent extends StatelessWidget {
  Widget _getData(BuildContext context, int index) {
    return Card(
      margin: EdgeInsets.all(10),
      child: Column(
        children: <Widget>[
          // 16/9的圖片
          AspectRatio(
            aspectRatio: 20 / 9,
            child: Image.network(
              listData[index]["imageUrl"],
              fit: BoxFit.cover,
            ),
          ),
          ListTile(
            leading: CircleAvatar(
              backgroundImage: NetworkImage(listData[index]["imageUrl"]),
            ),
            title: Text(listData[index]["title"]),
            subtitle: Text(
              listData[index]["author"],
              overflow: TextOverflow.ellipsis,
              maxLines: 1,
            ),
          )
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: ListView.builder(
        itemBuilder: _getData,
        itemCount: listData.length,
      ),
    );
  }
}
66.png
77.png

Wrap 實現(xiàn)瀑布流(橫向 或者 縱向)

單行的 Wrap 跟 Row 表現(xiàn)幾乎一致适瓦,單列的 Wrap 跟 Row實現(xiàn)效果也差不多。但是多行或者多列的時候谱仪,Wrap會根據(jù) 父控件的寬高玻熙,自動換行或者換列。疯攒。

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing: 10, //主軸間距
      runSpacing: 10, //次軸間距
      alignment: WrapAlignment.spaceAround, //對齊方式
      children: <Widget>[
        MyButton("shadow1"),
        MyButton("shadow2"),
        MyButton("shadow3"),
        MyButton("shadow4"),
        MyButton("shadow5"),
        MyButton("shadow6"),
        MyButton("shadow7"),
        MyButton("shadow8"),
        MyButton("shadow9"),
        MyButton("shadow10"),
        MyButton("shadow11"),
      ],
    );
  }
}

class MyButton extends StatelessWidget {
  String text;

  MyButton(this.text);

  @override
  Widget build(BuildContext context) {
    return RaisedButton(
        child: Text(this.text),
        textColor: Colors.pinkAccent,
        onPressed: () {
          print("hello shadow`滤妗P独称杨!");
        });
  }
}
88.png

有狀態(tài)組件

在 Flutter 中自定義組件其實就是一個類,這個類需要繼承 StatelessWidget/StatefulWidget筷转。
StatelessWidget 是無狀態(tài)組件,狀態(tài)不可變的 widget StatefulWidget 是有狀態(tài)組件悬而,持有的狀態(tài)可能在 widget 生命周期改變呜舒。通俗的講:如果我 們想改變頁面中的數(shù)據(jù)的話這個時候就需要用到 StatefulWidget

class HomeWidget extends StatefulWidget {
  @override
  MyState2 createState() => MyState2();
}

///自定義有狀態(tài)組件之動態(tài)計數(shù)器
class MyState extends State<HomeWidget> {
  int countNum = 1;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        SizedBox(
          height: 100,
        ),
        Chip(
          label: Text(this.countNum.toString()),
        ),
        RaisedButton(
          child: Text("添加"),
          onPressed: () {
            setState(() {
              this.countNum++;
              print(this.countNum);
            });
          },
        )
      ],
    );
  }
}

///自定義有狀態(tài)組件之動態(tài)添加列表數(shù)據(jù)
class MyState2 extends State<HomeWidget> {
  List mList = new List();

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Column(
          children: mList.map((value) {
            return ListTile(
              title: Text(value),
            );
          }).toList(),
        ),
        RaisedButton(
          child: Text("動態(tài)添加列表數(shù)據(jù)"),
          onPressed: () {
            setState(() {
              mList.add("hello shadow1");
              mList.add("hello shadow2");
            });
          },
        )
      ],
    );
  }
}

99.png

BottomNavigationBar 實現(xiàn)底部導航欄多頁面

BottomNavigationBar 是底部導航條,可以讓我們定義底部 Tab 切換笨奠,bottomNavigationBar 是 Scaffold 組件的參數(shù)

items    List<BottomNavigationBarItem>   底部導航條按鈕集合  
iconSize icon 圖標大小
currentIndex  默認選中第幾個
 onTap  選中變化回調(diào)函數(shù)
 fixedColor  選中的顏色 
type  底部按鈕的排放方式 BottomNavigationBarType.fixed 平均分配  --- BottomNavigationBarType.shifting 默認占據(jù)位置

下面實現(xiàn)了tab頁面切換的簡易小demo袭蝗,為頁面代碼做了拆分
mainDart

import 'package:flutter/material.dart';
import 'pages/Tabs.dart';

main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light(),
      title: "MaterialApp title",
      home: Tabs(),
    );
  }
}

Tabs.dart

import 'package:flutter/material.dart';
import 'package:flutter_demp/pages/tabs/CategoryPage.dart';
import 'package:flutter_demp/pages/tabs/HomePage.dart';
import 'package:flutter_demp/pages/tabs/MinePage.dart';
import 'package:flutter_demp/pages/tabs/ShopCartPage.dart';

class Tabs extends StatefulWidget {
  @override
  StateTabs createState() => StateTabs();
}

class StateTabs extends State<Tabs> {
//當前選擇的tab
  int _currentIndex = 0;
//page頁面集合
  List pageList = [HomePage(), CategoryPage(), ShopCartPage(), MinePage()];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("APPBar title"),
      ),
      body: pageList[_currentIndex], //根據(jù)底部tab切換唤殴,選擇不同的page界面
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首頁")),
          BottomNavigationBarItem(icon: Icon(Icons.category), title: Text("分類")),
          BottomNavigationBarItem(icon: Icon(Icons.shopping_cart), title: Text("購物車")),
          BottomNavigationBarItem( icon: Icon(Icons.supervised_user_circle), title: Text("我的")),
        ],
        onTap: (index) {
          setState(() { //tab切換選擇事件監(jiān)聽,更新狀態(tài)
            _currentIndex = index;
          });
        },
        currentIndex: _currentIndex, //當前選擇的tab
        fixedColor: Colors.pinkAccent, //選中時的顏色
        type: BottomNavigationBarType.fixed, //底部tab之間的排序方式
      ),
    );
  }
}

HomePage,其他的tab頁面與此類似

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text("我是首頁");
  }
}
10.png

自定義頂部導航按鈕 圖標到腥、顏色 以及 TabBar 定義頂部 Tab 切換

Flutter AppBar 自定義頂部按鈕圖 標朵逝、顏色

屬性     描述 
leading 在標題前面顯示的一個控件,在首頁通常顯示應用 的 logo乡范;在其他界面通常顯示為返回按鈕 
title 標題配名,通常顯示為當前界面的標題文字,可以放組 件 
actions 通常使用 IconButton 來表示晋辆,可以放按鈕組
 bottom 通常放 tabBar渠脉,標題下面顯示一個 Tab 導航欄 
backgroundColor 導航背景顏色 
iconTheme 圖標樣式 
textTheme 文字樣式
 centerTitle 標題是否居中顯示
class AppBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: AppBar(
            //左側(cè)按鈕
            leading: IconButton(
              icon: Icon(
                Icons.backspace,
              ),
              onPressed: () {
                print("left back onclick");
              },
            ),
            //右側(cè)按鈕
            actions: <Widget>[
              IconButton(
                icon: Icon(
                  Icons.menu,
                ),
                onPressed: () {
                  print("hello shadow menu");
                },
              ),
              IconButton(
                icon: Icon(
                  Icons.search,
                ),
                onPressed: () {
                  print("hello shadow search");
                },
              ),
            ],
            title: Text(
              "商品詳情",
            ),

            backgroundColor: Colors.pinkAccent,
            centerTitle: true,

            //頂部tab
            bottom: TabBar(
              tabs: <Widget>[
                Text("商品"),
                Text("詳情"),
              ],
              indicatorColor: Colors.blue,
            ),
          ),
          body: TabBarView(
            children: <Widget>[
              ListView(
                children: <Widget>[
                  ListTile(
                    title: Text("第一頁"),
                  ),
                  ListTile(
                    title: Text("第一頁"),
                  ),
                  ListTile(
                    title: Text("第一頁"),
                  )
                ],
              ),
              ListView(
                children: <Widget>[
                  ListTile(
                    title: Text("第二頁"),
                  ),
                  ListTile(
                    title: Text("第二頁"),
                  ),
                  ListTile(
                    title: Text("第二頁"),
                  )
                ],
              ),
            ],
          ),
        ));
  }
}

13.png

NavigationBar 頁面 實現(xiàn)tabBar
scaffold可以互相嵌套
DefaultTabController ,TabBar,TabBarView

 AppBar 中自定義 TabBar 實 現(xiàn)頂部 Tab 切換
TabBar  常見屬性:
屬性 描述
 tabs 顯示的標簽內(nèi)容,一般使用 Tab 對象,也可以是其他 的 Widget
 controller TabController 對象 
isScrollable   是否可滾動
 indicatorColor    指示器顏色
 indicatorWeight   指示器高度 
indicatorPadding    底部指示器的
 Padding indicator   指示器
 decoration瓶佳,  例如邊框等 
indicatorSize    指示器大小計算方式芋膘,
TabBarIndicatorSize.label   跟文 字等寬,
TabBarIndicatorSize.tab    跟每個 tab 等寬 
labelColor    選中 label 顏色
 labelStyle    選中 label 的 Style
 labelPadding   每個 label 的 padding 值
 unselectedLabelColor    未選中 label 顏色
 unselectedLabelStyle    未選中 label 的 Style

import 'package:flutter/material.dart';

class CategoryPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(
          title: Row(
            children: <Widget>[
              Expanded(
                child: TabBar(
                  labelColor: Colors.red,
                  indicatorColor: Colors.red,
                  unselectedLabelColor: Colors.white,
                  indicatorSize: TabBarIndicatorSize.label,
                  tabs: <Widget>[
                    Tab(
                      text: "hhhh",
                    ),
                    Tab(
                      text: "kkkk",
                    )
                  ],
                ),
              )
            ],
          ),
        ),
        body: TabBarView(
          children: <Widget>[Text("hhhhh"), Text("kkkkk")],
        ),
      ),
    );
  }
}

14.png

TabControl 實現(xiàn)頂部 tabBar

import 'dart:html';

import 'package:flutter/material.dart';

class TabControlPage extends StatefulWidget {

  @override
  _TabControlPageState createState() => _TabControlPageState();

  TabControlPage();
}

/// 使用TabControl創(chuàng)建tab,需要三個步驟霸饲,
/// 1.創(chuàng)建有狀態(tài)組件为朋,with SingleTickerProviderStateMixin
/// 2.初始化生命周期中,實現(xiàn)tabControl實例
/// 3.在 TabBar和TabBarView中賦值controller: _tabController屬性
class _TabControlPageState extends State<TabControlPage>
    with SingleTickerProviderStateMixin {
  TabController _tabController;

  ///生命周期函數(shù)厚脉,組件加載的時候調(diào)用
  @override
  void initState() {
    super.initState();

    //實現(xiàn)tabControl實例
    _tabController = TabController(length: 7, vsync: this);
    //tab 切換監(jiān)聽
    _tabController.addListener(() {
      print(_tabController.index);
    });
  }

  ///生命周期函數(shù) 組件關(guān)閉的時候被調(diào)用
  @override
  void dispose() {
    super.dispose();
    _tabController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("TabControl"),
        bottom: TabBar(
          isScrollable: true,
          tabs: <Widget>[
            Tab(
              text: "推薦1",
            ),
            Tab(
              text: "推薦2",
            ),
            Tab(
              text: "推薦3",
            ),
            Tab(
              text: "推薦4",
            ),
            Tab(
              text: "推薦5",
            ),
            Tab(
              text: "推薦6",
            ),
            Tab(
              text: "推薦7",
            ),
          ],
          controller: _tabController,
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: <Widget>[
          Text("推薦1"),
          Text("推薦2"),
          Text("推薦3"),
          Text("推薦4"),
          Text("推薦5"),
          Text("推薦6"),
          Text("推薦7"),
        ],
      ),
    );
  }
}
15.png

FlutterDrawer 側(cè)邊欄 抽屜樣式

在 Scaffold 組件里面?zhèn)魅?drawer 參數(shù)可以定義左側(cè)邊欄习寸,傳入 endDrawer 可以定義右側(cè)邊 欄。
側(cè)邊欄默認是隱藏的器仗,我們可以通過手指滑動顯示側(cè)邊欄融涣,也可以通過點擊按鈕顯示側(cè) 邊欄。

DrawerHeader 可以自定義布局
屬性   描述 
decoration   設置頂部背景顏色 
child    配置子元素 
padding    內(nèi)邊距 
margin    外邊距

UserAccountsDrawerHeader 固定格式
屬性 描述 
decoration   設置頂部背景顏色 
accountName   賬戶名稱 
accountEmail   賬戶郵箱
 currentAccountPicture   用戶頭像
 otherAccountsPictures   用來設置當前賬戶其他賬戶頭像 

 Widget build(BuildContext context) {
    return Scaffold(
      /*appBar: AppBar(
        title: Text("APPBar title"),
      ),*/
      body: pageList[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首頁")),
          BottomNavigationBarItem(
              icon: Icon(Icons.category), title: Text("分類")),
          BottomNavigationBarItem(
              icon: Icon(Icons.shopping_cart), title: Text("購物車")),
          BottomNavigationBarItem(
              icon: Icon(Icons.supervised_user_circle), title: Text("我的")),
        ],
        onTap: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
        currentIndex: _currentIndex,
        fixedColor: Colors.pinkAccent,
        type: BottomNavigationBarType.fixed,
      ),
      drawer: Drawer(
        child: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                Expanded(
                  /* child: DrawerHeader(
                        decoration: BoxDecoration(
                            image: DecorationImage(
                                image: NetworkImage(
                                    "https://www.itying.com/images/flutter/1.png"),fit: BoxFit.cover)),
                        child: Column(
                          children: <Widget>[
                            CircleAvatar(
                              backgroundImage: NetworkImage(
                                  "https://www.itying.com/images/flutter/3.png"),
                            ),
                            Text("付小影子")
                          ],
                        ))*/
                  child: UserAccountsDrawerHeader(
                    decoration: BoxDecoration(
                        image: DecorationImage(
                            image: NetworkImage(
                                "https://www.itying.com/images/flutter/1.png"),
                            fit: BoxFit.cover)),
                    accountName: Text("付小影子"),
                    accountEmail: Text("111111@qq.com"),
                    currentAccountPicture: CircleAvatar(
                      backgroundImage: NetworkImage(
                          "https://www.itying.com/images/flutter/3.png"),
                    ),
                  ),
                )
              ],
            ),
            ListTile(
              leading: Icon(Icons.home),
              title: Text("首頁中心"),
              onTap: () {
                print("跳轉(zhuǎn) 首頁");
              },
            ),
            Divider(),
            ListTile(
              leading: Icon(Icons.people),
              title: Text("用戶中心"),
              onTap: () {
                print("跳轉(zhuǎn) 用戶中心");
              },
            ),
            Divider(),
            ListTile(
              leading: Icon(Icons.settings),
              title: Text("設置中心"),
              onTap: () {
                print("跳轉(zhuǎn) 設置中心");
              },
            ),
            Divider(),
          ],
        ),
      ),
    );
  }

16.png

Flutter 按鈕組件

Flutter 里有很多的 Button 組件很多精钮,常見的按鈕組件有:RaisedButton威鹿、FlatButton、 IconButton轨香、OutlineButton忽你、ButtonBar、FloatingActionButton 等臂容。
RaisedButton :凸起的按鈕科雳,其實就是 Material Design 風格的 Button
FlatButton :扁平化的按鈕
OutlineButton:線框按鈕
IconButton :圖標按鈕
ButtonBar:按鈕組
FloatingActionButton:浮動按鈕

按鈕共用 屬性名稱 值類型 屬性值
onPressed VoidCallback ,一般接收一個 方法 必填參數(shù)脓杉,按下按鈕時觸發(fā)的回調(diào)糟秘,接收一個 方法,傳 null 表示按鈕禁用球散,會顯示禁用相關(guān) 樣式
child Widget 文本控件
textColor Color 文本顏色
color Color 按鈕的顏色
disabledColor Color 按鈕禁用時的顏色
disabledTextColor Color 按鈕禁用時的文本顏色
splashColor Color 點擊按鈕時水波紋的顏色
highlightColor Color 點擊(長按)按鈕后按鈕的顏色
elevation double 陰影的范圍尿赚,值越大陰影范圍越大
padding 內(nèi)邊距
shape 設置按鈕的形狀 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), )
shape: CircleBorder( side: BorderSide( color: Colors.white, ) )

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
                child: Text("普通按鈕"),
                onPressed: () {
                  print("普通按鈕");
                }),
            SizedBox(
              width: 10,
            ),
            RaisedButton(
                textColor: Colors.white,
                color: Colors.blue,
                child: Text("顏色按鈕"),
                onPressed: () {
                  print("顏色按鈕");
                }),
            SizedBox(
              width: 10,
            ),
            RaisedButton(
                textColor: Colors.white,
                color: Colors.blue,
                child: Text("陰影按鈕"),
                elevation: 10,
                onPressed: () {
                  print("陰影按鈕");
                }),
          ],
        ),
        SizedBox(
          height: 10,
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton.icon(
                icon: Icon(Icons.search),
                label: Text("圖標按鈕"),
                color: Colors.blue,
                textColor: Colors.white,
                onPressed: () {
                  print("圖標按鈕");
                }),
            SizedBox(
              width: 10,
            ),
            Container(
              width: 100,
              height: 30,
              child: RaisedButton(
                onPressed: () {
                  print("寬高固定");
                },
                child: Text("寬高按鈕"),
                textColor: Colors.white,
                color: Colors.pinkAccent,
              ),
            )
          ],
        ),
        SizedBox(
          height: 10,
        ),
        Row(
          children: <Widget>[
            Expanded(
                child: Container(
              height: 50,
              margin: EdgeInsets.all(20),
              child: RaisedButton(
                  child: Text("登錄"),
                  color: Colors.blue,
                  textColor: Colors.white,
                  onPressed: () {
                    print("登錄");
                  }),
            ))
          ],
        ),
        SizedBox(
          height: 10,
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              width: 100,
              height: 30,
              child: RaisedButton(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.circular(10))),
                onPressed: () {
                  print("圓角按鈕");
                },
                child: Text("圓角按鈕"),
                textColor: Colors.white,
                color: Colors.pinkAccent,
              ),
            ),
            SizedBox(
              width: 10,
            ),
            RaisedButton(
              shape: CircleBorder(
                  side: BorderSide(
                      style: BorderStyle.none, color: Colors.blue, width: 12)),
              onPressed: () {
                print("圓角按鈕");
              },
              child: Text("圓角按鈕"),
              textColor: Colors.white,
              color: Colors.pinkAccent,
            ),
          ],
        ),
        SizedBox(
          height: 10,
        ),
        Row(
          children: <Widget>[
            Expanded(
              child: Container(
                  height: 40,
                  margin: EdgeInsets.all(10),
                  child: FlatButton(
                      color: Colors.pink,
                      textColor: Colors.white,
                      onPressed: () {
                        print("扁平化的按鈕 ");
                      },
                      child: Text("扁平化的按鈕 "))),
            )
          ],
        ),
        SizedBox(
          height: 10,
        ),
        Row(
          children: <Widget>[
            Expanded(
              child: Container(
                  height: 40,
                  margin: EdgeInsets.all(10),
                  child: OutlineButton(
                      color: Colors.pink,
                      textColor: Colors.red,
                      borderSide: BorderSide(color: Colors.blue),
                      onPressed: () {
                        print("線框按鈕 ");
                      },
                      child: Text("線框按鈕"))),
            )
          ],
        )
      ],
    );
  }
}

17.png

FloatingActionButton 實現(xiàn) 底部 凸起按鈕效果

floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      floatingActionButton: Container(
        width: 50,
        height: 50,
        margin: EdgeInsets.only(top: 10),
        child: FloatingActionButton(
            child: Icon(Icons.add),
            backgroundColor:
                _currentIndex == 1 ? Colors.pinkAccent : Colors.yellow,
            onPressed: () {
              setState(() {
                _currentIndex = 1;
              });
            }),
      ),
18.png

輸入框組件 TextField

TextField 表單常見屬性:
maxLines :設置此參數(shù)可以把文本框改為多行文本框
onChanged: 文本框改變的時候觸發(fā)的事件
decoration
hintText: 類似 html 中的 placeholder
border :配置文本框邊框 OutlineInputBorder 配合使用
labelText :lable 的名稱
labelStyle :配置 lable 的樣式
obscureText: 把文本框框改為密碼框
controller: controller 結(jié)合 TextEditingController()可以配置表單默認顯示的內(nèi)容
Checkbox 常見屬性:
value: true 或者 false
onChanged: 改變的時候觸發(fā)的事件
activeColor: 選中的顏色、背景顏色
checkColor: 選中的顏色、Checkbox 里面對號的顏色
CheckboxListTile 常見屬性:
value: true 或者 false
onChanged: 改變的時候觸發(fā)的事件
activeColor: 選中的顏色凌净、背景顏色
title: 標題
subtitle: 二級標題
secondary: 配置圖標或者圖片
selected: 選中的時候文字顏色是否跟著改變


class _State extends State<MyApp> {
  //設置初始值
  var _textControl = TextEditingController();
  bool _isSelect = true;

  @override
  void initState() {
    super.initState();
    _textControl.text = "付小影子";
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "flutter demo",
      theme: ThemeData.light(),
      home: Scaffold(
        appBar: AppBar(
          title: Text("輸入框"),
        ),
        body: Padding(
          padding: EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              TextField(
                //密碼框
                obscureText: true,
                //單行 or 多行 設置
                maxLines: 1,
                //輸入框樣式
                decoration: InputDecoration(
                  //提示文字
                  hintText: "請輸入用戶名稱",
                  labelText: "用戶名",
                  icon: Icon(Icons.people),
                  //帶邊框
                  border: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.redAccent),
                  ),
                ),
                //初始值設置
                controller: _textControl,
                //輸入監(jiān)聽
                onChanged: (value) {
                  setState(() {
                    _textControl.text = value;
                    print(value);
                  });
                },
              ),
              SizedBox(
                height: 10,
              ),
              Container(
                //寬度 match_patch
                width: double.infinity,
                child: RaisedButton(
                    child: Text("登錄"),
                    onPressed: () {
                      print("輸入框內(nèi)容${_textControl.text}");
                    }),
              ),
              SizedBox(
                height: 10,
              ),
              Checkbox(
                  value: _isSelect,
                  onChanged: (b) {
                    setState(() {
                      _isSelect = b;
                      print(b ? "選中" : "未選中");
                    });
                  }),
              SizedBox(
                height: 10,
              ),
              CheckboxListTile(
                  title: Text("checkbox title"),
                  subtitle: Text("checkbox subtitle"),
                  secondary: Icon(Icons.people),
                  value: _isSelect,
                  onChanged: (b) {
                    setState(() {
                      _isSelect = b;
                      print(b ? "選中" : "未選中");
                    });
                  })
            ],
          ),
        ),
      ),
    );
  }
}
19.png

Radio悲龟、RadioListTile 單選按鈕組件

當value的值跟groupValue 的值一致時,意味著選中該按鈕冰寻。须教。groupValue 值對應變量為同一個,視為同一組單選按鈕斩芭,互斥
Radio 常用屬性:
value :單選的值
onChanged: 改變時觸發(fā)
activeColor :選中的顏色轻腺、背景顏色
groupValue :選擇組的值
RadioListTile 常用屬性:
value: true 或者 false
onChanged: 改變的時候觸發(fā)的事件
activeColor: 選中的顏色、背景顏色
title: 標題
subtitle: 二級標題
secondary: 配置圖標或者圖片
groupValue: 選擇組的值

class _MyAPPState extends State<MyAPP> {
  //性別 1男  2女
  int sex = 1;
  var flag = true;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "Flutter demo",
        theme: ThemeData.light(),
        home: Scaffold(
          appBar: AppBar(
            title: Text("Radio 單選框"),
          ),
          body: Padding(
            padding: EdgeInsets.all(20),
            child: Column(
              children: <Widget>[
                Row(
                  children: <Widget>[
                    Text("男:"),
                    Radio<int>(
                        value: 1,
                        groupValue: sex,
                        onChanged: (value) {
                          setState(() {
                            sex = value;
                          });
                        }),
                    SizedBox(width: 10),
                    Text("女:"),
                    Radio<int>(
                        value: 2,
                        groupValue: sex,
                        onChanged: (value) {
                          setState(() {
                            sex = value;
                          });
                        })
                  ],
                ),
                SizedBox(
                  height: 10,
                ),
                RadioListTile(
                    value: 1,
                    groupValue: sex,
                    title: Text("Title"),
                    subtitle: Text("subTitle"),
                    selected: sex == 1,
                    secondary: Icon(Icons.print),
                    onChanged: (value) {
                      setState(() {
                        sex = value;
                      });
                    }),
                SizedBox(height: 10),
                RadioListTile(
                    value: 2,
                    groupValue: sex,
                    selected: sex == 2,
                    title: Text("第二個 title"),
                    subtitle: Text("第二個 subTitle"),
                    secondary: Image.network(
                        "https://www.itying.com/images/flutter/3.png"),
                    onChanged: (value) {
                      setState(() {
                        sex = value;
                      });
                    }),
                SizedBox(
                  height: 10,
                ),
                Text(sex == 1 ? "選中男生" : "選中女生"),
                Switch(
                    value: flag,
                    onChanged: (value) {
                      setState(() {
                        flag = value;
                      });
                    })
              ],
            ),
          ),
        ));
  }
}
23.png

開關(guān) Switch

value: 單選的值
onChanged: 改變時觸發(fā)
activeColor: 選中的顏色秒旋、背景顏色

Switch(
                    value: flag,
                    onChanged: (value) {
                      setState(() {
                        flag = value;
                      });
                    })

表單 demo小綜合

import 'package:flutter/material.dart';

main() {
  runApp(FormDemoPage());
}

class FormDemoPage extends StatefulWidget {
  FormDemoPage({Key key}) : super(key: key);

  _FormDemoPageState createState() => _FormDemoPageState();
}

class _FormDemoPageState extends State<FormDemoPage> {
  String username;
  int sex = 1;
  String info = '';

  List hobby = [
    {"checked": true, "title": "吃飯"},
    {"checked": false, "title": "睡覺"},
    {"checked": true, "title": "寫代碼"}
  ];

  List<Widget> _getHobby() {
    List<Widget> tempList = [];

    for (var i = 0; i < this.hobby.length; i++) {
      tempList.add(Row(
        children: <Widget>[
          Text(this.hobby[i]["title"] + ":"),
          Checkbox(
              value: this.hobby[i]["checked"],
              onChanged: (value) {
                setState(() {
                  this.hobby[i]["checked"] = value;
                });
              })
        ],
      ));
    }
    return tempList;
  }

  void _sexChanged(value) {
    setState(() {
      this.sex = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "表單 demo",
      home: Scaffold(
        appBar: AppBar(
          title: Text("學員信息登記系統(tǒng)"),
        ),
        body: Padding(
          padding: EdgeInsets.all(20),
          child: Column(
            children: <Widget>[
              TextField(
                decoration: InputDecoration(hintText: "輸入用戶信息"),
                onChanged: (value) {
                  setState(() {
                    this.username = value;
                  });
                },
              ),
              SizedBox(height: 10),
              Row(
                children: <Widget>[
                  Text("男"),
                  Radio(
                      value: 1,
                      onChanged: this._sexChanged,
                      groupValue: this.sex),
                  SizedBox(width: 20),
                  Text("女"),
                  Radio(
                      value: 2,
                      onChanged: this._sexChanged,
                      groupValue: this.sex)
                ],
              ),

              //愛好
              SizedBox(height: 40),
              Column(
                children: this._getHobby(),
              ),

              TextField(
                maxLines: 4,
                decoration: InputDecoration(
                    hintText: "描述信息", border: OutlineInputBorder()),
                onChanged: (value) {
                  setState(() {
                    this.info = value;
                  });
                },
              ),

              SizedBox(height: 40),
              Container(
                width: double.infinity,
                height: 40,
                child: RaisedButton(
                  child: Text("提交信息"),
                  onPressed: () {
                    print(this.sex);
                    print(this.username);
                    print(this.hobby);
                  },
                  color: Colors.blue,
                  textColor: Colors.white,
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
21.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末约计,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子迁筛,更是在濱河造成了極大的恐慌煤蚌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件细卧,死亡現(xiàn)場離奇詭異尉桩,居然都是意外死亡,警方通過查閱死者的電腦和手機贪庙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門蜘犁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人止邮,你說我怎么就攤上這事这橙。” “怎么了导披?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵屈扎,是天一觀的道長。 經(jīng)常有香客問我撩匕,道長鹰晨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任止毕,我火速辦了婚禮模蜡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扁凛。我一直安慰自己忍疾,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布谨朝。 她就那樣靜靜地躺著膝昆,像睡著了一般丸边。 火紅的嫁衣襯著肌膚如雪叠必。 梳的紋絲不亂的頭發(fā)上荚孵,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音纬朝,去河邊找鬼收叶。 笑死,一個胖子當著我的面吹牛共苛,可吹牛的內(nèi)容都是我干的判没。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼隅茎,長吁一口氣:“原來是場噩夢啊……” “哼澄峰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辟犀,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤俏竞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后堂竟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魂毁,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年出嘹,在試婚紗的時候發(fā)現(xiàn)自己被綠了席楚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡税稼,死狀恐怖烦秩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情郎仆,我是刑警寧澤只祠,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站丸升,受9級特大地震影響铆农,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狡耻,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一墩剖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夷狰,春花似錦岭皂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽书劝。三九已至,卻和暖如春土至,著一層夾襖步出監(jiān)牢的瞬間购对,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工陶因, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留骡苞,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓楷扬,卻偏偏與公主長得像解幽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子烘苹,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355