Flutter 128: 圖解 ColorTween 顏色補(bǔ)間動(dòng)畫 & ButtonBar 按鈕容器

????小菜在嘗試做主題顏色切換時(shí),希望背景色有一個(gè)自然的過(guò)渡過(guò)程,于是了解到 ColorTween 顏色補(bǔ)間差值器,配合 AnimationController 實(shí)現(xiàn)兩種顏色間的自然過(guò)渡疟呐;小菜簡(jiǎn)單嘗試一下;

ColorTween

源碼分析

????ColorTween 的源碼很簡(jiǎn)單东且,繼承自 Tween 補(bǔ)間動(dòng)畫启具,與 Tween 相同,只是 beginendColor 替代珊泳;其中若需要透明狀態(tài)鲁冯,可以將 begin / end 設(shè)置為 null拷沸;Colors.transparent 再此代表黑色透明,會(huì)淡入淡出黑色薯演;

class ColorTween extends Tween<Color?> {
  ColorTween({ Color? begin, Color? end }) : super(begin: begin, end: end);

  @override
  Color? lerp(double t) => Color.lerp(begin, end, t);
}

案例源碼

????小菜預(yù)先設(shè)置好需要主題顏色切換的 UI Widget撞芍,之后通過(guò)混入 TickerProviderStateMixin,在 initState() 初始化時(shí)設(shè)置好 AnimationController跨扮,將顏色傳遞給背景色序无;

AnimationController _controller;
Animation<Color> _colors;
Color _currentColor = Colors.black;

@override
void initState() {
  super.initState();
  _controller = AnimationController(duration: Duration(seconds: 3), vsync: this);
  _colors = ColorTween(begin: _currentColor, end: Colors.amber).animate(_controller);
}

_bodyWid() => Material(
    child: AnimatedBuilder(
        animation: _colors,
        builder: (BuildContext _, Widget childWidget) {
          return Scaffold(backgroundColor: _colors.value, body: _itemListWid());
        }));

????通過(guò) AnimationController 控制淡入淡出時(shí)機(jī);reset() 重置控制器衡创,forward()beginend 顏色切換帝嗡;reward()endbegin 顏色切換周拐;repeat() 重復(fù)循環(huán)切換怕磨;

_changeColorWid() => Container(
    color: Colors.white,
    child: Column(children: [
      ListTile(title: Text('切換 ThemeColor:')),
      Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
        _itemColorWid(Colors.deepOrange), _itemColorWid(Colors.teal),
        _itemColorWid(Colors.blue), _itemColorWid(Colors.pink),
        _itemColorWid(Colors.indigoAccent)
      ])
    ]));

_itemColorWid(color) => GestureDetector(
    child: Container(width: 50.0, height: 50.0, color: color),
    onTap: () {
      _colors = ColorTween(begin: _currentColor, end: color).animate(_controller);
      setState(() {
        _controller.reset();
        _controller.forward();
      });
      _currentColor = color;
    });

ButtonBar

????小菜在很多場(chǎng)景中設(shè)置水平均分或右對(duì)齊黄痪,為此小菜了解到一個(gè)新的容器方式苍糠,ButtonBar 默認(rèn)水平方式放置子 Widget 當(dāng)水平寬度無(wú)法完全放置所有子 Widget 時(shí)會(huì)豎直方向放置沪悲,小菜簡(jiǎn)單學(xué)習(xí)一下卷中;

源碼分析

const ButtonBar({
    Key key,
    this.alignment,         // 對(duì)齊方式
    this.mainAxisSize,      // 主軸上占據(jù)空間范圍
    this.buttonTextTheme,   // 按鈕文本主題
    this.buttonMinWidth,    // 子按鈕最小寬度
    this.buttonHeight,      // 子按鈕最高度
    this.buttonPadding,     // 子按鈕內(nèi)邊距
    this.buttonAlignedDropdown, // 下拉菜單是否與子按鈕對(duì)齊
    this.layoutBehavior,
    this.overflowDirection, // 子按鈕排列順序
    this.overflowButtonSpacing, // 子按鈕之間間距
    this.children = const <Widget>[],
})

????簡(jiǎn)單分析源碼脖苏,ButtonBar 作為一個(gè)無(wú)狀態(tài)的 StatelessWidgetRow 類似方灾,作為一個(gè)存放子 Widget 的容器塘秦,其中包括了類似于對(duì)齊方式等屬性方便應(yīng)用讼渊;小菜簡(jiǎn)單理解為變形的 Row,實(shí)際是繼承自 Flex_ButtonBarRow尊剔;

案例嘗試

構(gòu)造方法

????ButtonBar 作為一個(gè) Widget 容器爪幻,用于水平存放各 Widget,若子 Widget 占據(jù)空間范圍大于分配空間時(shí)须误,則豎直方向展示挨稿;

_buttonBarWid01() => ButtonBar(children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02'), onPressed: null) ]);
    
_buttonBarWid02() => ButtonBar(children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02'), onPressed: null),
      RaisedButton(child: Text('Button 03'), onPressed: null),
      RaisedButton(child: Text('Button 04'), onPressed: null) ]);
    
_buttonBarWid03() => ButtonBar(children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02'), onPressed: null),
      RaisedButton(child: Text('Button 03'), onPressed: null),
      RaisedButton(child: Text('Button 04'), onPressed: null),
      RaisedButton(child: Text('Button 05'), onPressed: null) ]);

1. alignment

????alignment 為容器內(nèi)子 Widget 的對(duì)齊方式,不設(shè)置或?yàn)?null 時(shí)默認(rèn)為 end 方式對(duì)齊京痢,此時(shí)與 ltr / rtl 相關(guān)奶甘;

_buttonBarWid01(index) {
  MainAxisAlignment alignment;
  if (index == 0) {
    alignment = MainAxisAlignment.start;
  } else if (index == 1) {
    alignment = MainAxisAlignment.center;
  } else if (index == 2) {
    alignment = MainAxisAlignment.spaceAround;
  } else if (index == 3) {
    alignment = MainAxisAlignment.spaceBetween;
  } else if (index == 4) {
    alignment = MainAxisAlignment.spaceEvenly;
  } else {
    alignment = MainAxisAlignment.end;
  }
  return ButtonBar(alignment: alignment, children: <Widget>[
    RaisedButton(child: Text('Button'), onPressed: null),
    RaisedButton(child: Text('${alignment.toString()}'), onPressed: null) ]);
}

2. mainAxisSize

????mainAxisSize 為主軸上占據(jù)空間范圍,與 Row / Column 一致祭椰,分為 min / max 最小范圍和最大填充范圍兩種臭家;

_buttonBarWid05(mainAxisSize) => Container(
    color: Colors.blue.withOpacity(0.3),
    child: ButtonBar(mainAxisSize: mainAxisSize, children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02'), onPressed: null),
      RaisedButton(child: Text('Button 03'), onPressed: null)
    ]));

3. buttonTextTheme

????buttonTextTheme 為子 Widget 按鈕主題,主要包括 normal / accent / primary 三種主題樣式方淤,分別對(duì)應(yīng) ThemeData.brightness / accentColor / primaryColor钉赁;

_buttonBarWid04(theme) =>
    ButtonBar(buttonTextTheme: theme, children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02', style: TextStyle(color: Colors.blue)), onPressed: null),
      RaisedButton(child: Text('${theme.toString()}'), onPressed: null),
    ]);

4. buttonMinWidth & buttonHeight

????buttonMinWidth & buttonHeight 分別對(duì)應(yīng)子 Widget 默認(rèn)的最小按鈕寬度和按鈕高度;

_buttonBarWid06(width, height, alignment) =>
    ButtonBar(buttonMinWidth: width, buttonHeight: height, children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02', style: TextStyle(color: Colors.blue)), onPressed: null),
      RaisedButton(child: Text('${alignment.toString()}'), onPressed: null),
    ]);

5. overflowButtonSpacing & buttonPadding

????overflowButtonSpacing 對(duì)應(yīng)子按鈕外間距携茂,類似于 GridView 元素間間距你踩;buttonPadding 對(duì)應(yīng)子按鈕內(nèi)邊距;

_buttonBarWid07(padding, spacing) => ButtonBar(
      overflowButtonSpacing: spacing,
      buttonPadding: EdgeInsets.all(padding),
      children: <Widget>[
        RaisedButton(child: Text('Button 01'), onPressed: null),
        RaisedButton(child: Text('Button 02', style: TextStyle(color: Colors.blue)), onPressed: null),
        RaisedButton(child: Text('Button 03'), onPressed: null)
      ]);

6. overflowDirection

????overflowDirection 為若容器內(nèi)子 Widget 所占范圍超過(guò)最大限制范圍時(shí),垂直排列順序姓蜂,小菜理解為順序和倒序兩種按厘;

_buttonBarWid08(direction) =>
    ButtonBar(overflowDirection: direction, children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02', style: TextStyle(color: Colors.blue)), onPressed: null),
      RaisedButton(child: Text('Button 03'), onPressed: null),
      RaisedButton(child: Text('${direction.toString()}'), onPressed: null),
    ]);

????ColorTween 案例源碼 & ButtonBar 案例源碼


????ColorTweenButtonBar 的應(yīng)用非常簡(jiǎn)單,這次小菜在實(shí)際場(chǎng)景中進(jìn)行嘗試學(xué)習(xí)钱慢,如有錯(cuò)誤逮京,請(qǐng)多多指導(dǎo)!

來(lái)源: 阿策小和尚

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末束莫,一起剝皮案震驚了整個(gè)濱河市懒棉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌览绿,老刑警劉巖策严,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異饿敲,居然都是意外死亡妻导,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門怀各,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)倔韭,“玉大人,你說(shuō)我怎么就攤上這事瓢对∈僮茫” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵硕蛹,是天一觀的道長(zhǎng)醇疼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)法焰,這世上最難降的妖魔是什么秧荆? 我笑而不...
    開(kāi)封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮埃仪,結(jié)果婚禮上辰如,老公的妹妹穿的比我還像新娘。我一直安慰自己贵试,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布凯正。 她就那樣靜靜地躺著毙玻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪廊散。 梳的紋絲不亂的頭發(fā)上桑滩,一...
    開(kāi)封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音允睹,去河邊找鬼运准。 笑死幌氮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胁澳。 我是一名探鬼主播该互,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼韭畸!你這毒婦竟也來(lái)了宇智?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤胰丁,失蹤者是張志新(化名)和其女友劉穎随橘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體锦庸,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡机蔗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了甘萧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片萝嘁。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖幔嗦,靈堂內(nèi)的尸體忽然破棺而出酿愧,到底是詐尸還是另有隱情,我是刑警寧澤邀泉,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布嬉挡,位于F島的核電站,受9級(jí)特大地震影響汇恤,放射性物質(zhì)發(fā)生泄漏庞钢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一因谎、第九天 我趴在偏房一處隱蔽的房頂上張望基括。 院中可真熱鬧,春花似錦财岔、人聲如沸风皿。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)桐款。三九已至,卻和暖如春夷恍,著一層夾襖步出監(jiān)牢的瞬間魔眨,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遏暴,地道東北人侄刽。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像朋凉,于是被迫代替她去往敵國(guó)和親州丹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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