Flutter Widget2

widget使用合集

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

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

stack 有點(diǎn)類似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ù)設(shè)置調(diào)整子元素 child 的寬高比

AspectRation 的子元素 寬度 占據(jù) 父組件,高度根據(jù)寬高比而定,aspectRatio設(shè)置寬高比 比如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 實(shí)現(xiàn)瀑布流(橫向 或者 縱向)

單行的 Wrap 跟 Row 表現(xiàn)幾乎一致,單列的 Wrap 跟 Row實(shí)現(xiàn)效果也差不多。但是多行或者多列的時(shí)候,Wrap會(huì)根據(jù) 父控件的寬高,自動(dòng)換行或者換列。。

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing: 10, //主軸間距
      runSpacing: 10, //次軸間距
      alignment: WrapAlignment.spaceAround, //對(duì)齊方式
      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?。?!");
        });
  }
}
88.png

有狀態(tài)組件

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

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

///自定義有狀態(tài)組件之動(dòng)態(tài)計(jì)數(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)組件之動(dòng)態(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("動(dòng)態(tài)添加列表數(shù)據(jù)"),
          onPressed: () {
            setState(() {
              mList.add("hello shadow1");
              mList.add("hello shadow2");
            });
          },
        )
      ],
    );
  }
}

99.png

BottomNavigationBar 實(shí)現(xiàn)底部導(dǎo)航欄多頁面

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

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

下面實(shí)現(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> {
//當(dāng)前選擇的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, //當(dāng)前選擇的tab
        fixedColor: Colors.pinkAccent, //選中時(shí)的顏色
        type: BottomNavigationBarType.fixed, //底部tab之間的排序方式
      ),
    );
  }
}

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

import 'package:flutter/material.dart';

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

自定義頂部導(dǎo)航按鈕 圖標(biāo)、顏色 以及 TabBar 定義頂部 Tab 切換

Flutter AppBar 自定義頂部按鈕圖 標(biāo)、顏色

屬性     描述 
leading 在標(biāo)題前面顯示的一個(gè)控件,在首頁通常顯示應(yīng)用 的 logo;在其他界面通常顯示為返回按鈕 
title 標(biāo)題,通常顯示為當(dāng)前界面的標(biāo)題文字,可以放組 件 
actions 通常使用 IconButton 來表示,可以放按鈕組
 bottom 通常放 tabBar,標(biāo)題下面顯示一個(gè) Tab 導(dǎo)航欄 
backgroundColor 導(dǎo)航背景顏色 
iconTheme 圖標(biāo)樣式 
textTheme 文字樣式
 centerTitle 標(biāo)題是否居中顯示
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 頁面 實(shí)現(xiàn)tabBar
scaffold可以互相嵌套
DefaultTabController ,TabBar,TabBarView

 AppBar 中自定義 TabBar 實(shí) 現(xiàn)頂部 Tab 切換
TabBar  常見屬性:
屬性 描述
 tabs 顯示的標(biāo)簽內(nèi)容,一般使用 Tab 對(duì)象,也可以是其他 的 Widget
 controller TabController 對(duì)象 
isScrollable   是否可滾動(dòng)
 indicatorColor    指示器顏色
 indicatorWeight   指示器高度 
indicatorPadding    底部指示器的
 Padding indicator   指示器
 decoration,  例如邊框等 
indicatorSize    指示器大小計(jì)算方式,
TabBarIndicatorSize.label   跟文 字等寬,
TabBarIndicatorSize.tab    跟每個(gè) tab 等寬 
labelColor    選中 label 顏色
 labelStyle    選中 label 的 Style
 labelPadding   每個(gè) 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 實(shí)現(xiàn)頂部 tabBar

import 'dart:html';

import 'package:flutter/material.dart';

class TabControlPage extends StatefulWidget {

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

  TabControlPage();
}

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

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

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

  ///生命周期函數(shù) 組件關(guān)閉的時(shí)候被調(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è)邊欄默認(rèn)是隱藏的,我們可以通過手指滑動(dòng)顯示側(cè)邊欄,也可以通過點(diǎn)擊按鈕顯示側(cè) 邊欄。

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

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

 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("設(shè)置中心"),
              onTap: () {
                print("跳轉(zhuǎn) 設(shè)置中心");
              },
            ),
            Divider(),
          ],
        ),
      ),
    );
  }

16.png

Flutter 按鈕組件

Flutter 里有很多的 Button 組件很多,常見的按鈕組件有:RaisedButton、FlatButton、 IconButton、OutlineButton、ButtonBar、FloatingActionButton 等。
RaisedButton :凸起的按鈕,其實(shí)就是 Material Design 風(fēng)格的 Button
FlatButton :扁平化的按鈕
OutlineButton:線框按鈕
IconButton :圖標(biāo)按鈕
ButtonBar:按鈕組
FloatingActionButton:浮動(dòng)按鈕

按鈕共用 屬性名稱 值類型 屬性值
onPressed VoidCallback ,一般接收一個(gè) 方法 必填參數(shù),按下按鈕時(shí)觸發(fā)的回調(diào),接收一個(gè) 方法,傳 null 表示按鈕禁用,會(huì)顯示禁用相關(guān) 樣式
child Widget 文本控件
textColor Color 文本顏色
color Color 按鈕的顏色
disabledColor Color 按鈕禁用時(shí)的顏色
disabledTextColor Color 按鈕禁用時(shí)的文本顏色
splashColor Color 點(diǎn)擊按鈕時(shí)水波紋的顏色
highlightColor Color 點(diǎn)擊(長按)按鈕后按鈕的顏色
elevation double 陰影的范圍,值越大陰影范圍越大
padding 內(nèi)邊距
shape 設(shè)置按鈕的形狀 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("圖標(biāo)按鈕"),
                color: Colors.blue,
                textColor: Colors.white,
                onPressed: () {
                  print("圖標(biāo)按鈕");
                }),
            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 實(shí)現(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è)置此參數(shù)可以把文本框改為多行文本框
onChanged: 文本框改變的時(shí)候觸發(fā)的事件
decoration
hintText: 類似 html 中的 placeholder
border :配置文本框邊框 OutlineInputBorder 配合使用
labelText :lable 的名稱
labelStyle :配置 lable 的樣式
obscureText: 把文本框框改為密碼框
controller: controller 結(jié)合 TextEditingController()可以配置表單默認(rèn)顯示的內(nèi)容
Checkbox 常見屬性:
value: true 或者 false
onChanged: 改變的時(shí)候觸發(fā)的事件
activeColor: 選中的顏色、背景顏色
checkColor: 選中的顏色、Checkbox 里面對(duì)號(hào)的顏色
CheckboxListTile 常見屬性:
value: true 或者 false
onChanged: 改變的時(shí)候觸發(fā)的事件
activeColor: 選中的顏色、背景顏色
title: 標(biāo)題
subtitle: 二級(jí)標(biāo)題
secondary: 配置圖標(biāo)或者圖片
selected: 選中的時(shí)候文字顏色是否跟著改變


class _State extends State<MyApp> {
  //設(shè)置初始值
  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 多行 設(shè)置
                maxLines: 1,
                //輸入框樣式
                decoration: InputDecoration(
                  //提示文字
                  hintText: "請(qǐng)輸入用戶名稱",
                  labelText: "用戶名",
                  icon: Icon(Icons.people),
                  //帶邊框
                  border: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.redAccent),
                  ),
                ),
                //初始值設(shè)置
                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 單選按鈕組件

當(dāng)value的值跟groupValue 的值一致時(shí),意味著選中該按鈕。。groupValue 值對(duì)應(yīng)變量為同一個(gè),視為同一組單選按鈕,互斥
Radio 常用屬性:
value :單選的值
onChanged: 改變時(shí)觸發(fā)
activeColor :選中的顏色、背景顏色
groupValue :選擇組的值
RadioListTile 常用屬性:
value: true 或者 false
onChanged: 改變的時(shí)候觸發(fā)的事件
activeColor: 選中的顏色、背景顏色
title: 標(biāo)題
subtitle: 二級(jí)標(biāo)題
secondary: 配置圖標(biāo)或者圖片
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("第二個(gè) title"),
                    subtitle: Text("第二個(gè) 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: 改變時(shí)觸發(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("學(xué)員信息登記系統(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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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