【Flutter】TabBar 改背景色

之前有提過要仿公司 某款產(chǎn)品的UI,用Flutter剛好試試手旅东。首頁登陸都做了灭抑,有幾個(gè)坑記錄一下。
這里展示的功能其實(shí)都應(yīng)該從后端獲取的抵代,后端這一塊目前沒做腾节,后面有空了補(bǔ)起來。
相對(duì)比較簡單荤牍,主要涉及到以下幾點(diǎn):
1案腺、TabBar上無法設(shè)置顏色和高度,標(biāo)準(zhǔn)庫默認(rèn)與AppBar顏色一致参淫。
2救湖、GridView的基本運(yùn)用。

import 'package:flutter/material.dart';
import 'Pages/Workpage.dart' show WorkPages;
import 'Pages/Salespage.dart' show SalesPages;
import 'Pages/WareHousePage.dart' show WareHousePages;
import 'Pages/Purchasepage.dart' show PurchasePages;
import 'config/conf.dart' show GlobalVariable;

class HomePages extends StatefulWidget {
  @override
  _HomePagesState createState() => _HomePagesState();
}

class _HomePagesState extends State<HomePages> {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: 4,
        child: Scaffold(
          appBar: AppBar(
              elevation: 0,
              centerTitle: true,
              automaticallyImplyLeading: true,
              actions: <Widget>[
                Image.asset('assets/images/temp_setting.png', width: 26.0, height: 26.0,),
                SizedBox(width: 5.0,)
              ],
              title: RichText(
                text: TextSpan(children: [
                  TextSpan(text: GlobalVariable.AppHomeTitle, style: TextStyle(fontSize: 20.0)),
                  TextSpan(text: GlobalVariable.AppHomeSubTitle, style: TextStyle(fontSize: 12.0))
                ]),
              ),

              //可以單獨(dú)設(shè)置涎才,固定高度為40H
              bottom: PreferredSize(
                preferredSize: Size.fromHeight(40),
                child: Material(
                  color: Colors.white,
                  child: TabBar(
                      labelPadding: EdgeInsets.all(10.0),
                      labelStyle: TextStyle(fontSize: 16.0),
                      unselectedLabelColor: Colors.black54,
                      labelColor: Colors.blue,
                    tabs: <Widget>[
                        Text('采購管理'),
                        Text('生產(chǎn)管理'),
                        Text('倉庫管理'),
                        Text('銷售管理'),
                    ],
                  ),
                )
              )),
          body: Container(
            color: Colors.white,
            child: TabBarView(
              children: <Widget>[
                PurchasePages(),
                WorkPages(),
                WareHousePages(),
                SalesPages(),
              ],
            ),
          )
        ));
  }
}

這里的bottom下沒有直接TabBar鞋既,而且用PreferredSize來進(jìn)行取代。如果直接用TabBar的話耍铜,顏色會(huì)與頂部一致邑闺,并且無法更改。

這里可以看到TabBar的屬性,并沒有任何顏色的屬性棕兼? 那要如何改顏色陡舅?

 class TabBar extends StatefulWidget implements PreferredSizeWidget {
  /// Creates a material design tab bar.
  ///
  /// The [tabs] argument must not be null and its length must match the [controller]'s
  /// [TabController.length].
  ///
  /// If a [TabController] is not provided, then there must be a
  /// [DefaultTabController] ancestor.
  ///
  /// The [indicatorWeight] parameter defaults to 2, and must not be null.
  ///
  /// The [indicatorPadding] parameter defaults to [EdgeInsets.zero], and must not be null.
  ///
  /// If [indicator] is not null, then [indicatorWeight], [indicatorPadding], and
  /// [indicatorColor] are ignored.
  const TabBar({
    Key key,
    @required this.tabs,
    this.controller,
    this.isScrollable = false,
    this.indicatorColor,
    this.indicatorWeight = 2.0,
    this.indicatorPadding = EdgeInsets.zero,
    this.indicator,
    this.indicatorSize,
    this.labelColor,
    this.labelStyle,
    this.labelPadding,
    this.unselectedLabelColor,
    this.unselectedLabelStyle,
    this.dragStartBehavior = DragStartBehavior.start,
    this.onTap,
  }) : assert(tabs != null),
       assert(isScrollable != null),
       assert(dragStartBehavior != null),
       assert(indicator != null || (indicatorWeight != null && indicatorWeight > 0.0)),
       assert(indicator != null || (indicatorPadding != null)),
       super(key: key);
}

我們看到TabBar繼承了PreferredSizeWidget,點(diǎn)進(jìn)去看下伴挚,經(jīng)過觀察靶衍,我們可以使用它重新布局畫面。

記住一定要在Material下茎芋,單獨(dú)設(shè)置顏色

// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/rendering.dart';

import 'basic.dart';
import 'framework.dart';

/// An interface for widgets that can return the size this widget would prefer
/// if it were otherwise unconstrained.
///
/// There are a few cases, notably [AppBar] and [TabBar], where it would be
/// undesirable for the widget to constrain its own size but where the widget
/// needs to expose a preferred or "default" size. For example a primary
/// [Scaffold] sets its app bar height to the app bar's preferred height
/// plus the height of the system status bar.
///
/// Use [PreferredSize] to give a preferred size to an arbitrary widget.
abstract class PreferredSizeWidget implements Widget {

  /// The size this widget would prefer if it were otherwise unconstrained.
  ///
  /// In many cases it's only necessary to define one preferred dimension.
  /// For example the [Scaffold] only depends on its app bar's preferred
  /// height. In that case implementations of this method can just return
  /// `new Size.fromHeight(myAppBarHeight)`;
  Size get preferredSize;
}

/// A widget with a preferred size.
///
/// This widget does not impose any constraints on its child, and it doesn't
/// affect the child's layout in any way. It just advertises a preferred size
/// which can be used by the parent.
///
/// See also:
///
///  * [AppBar.bottom] and [Scaffold.appBar], which require preferred size widgets.
///  * [PreferredSizeWidget], the interface which this widget implements to expose
///    its preferred size.
///  * [AppBar] and [TabBar], which implement PreferredSizeWidget.
class PreferredSize extends StatelessWidget implements PreferredSizeWidget {
  /// Creates a widget that has a preferred size.
  const PreferredSize({
    Key key,
    @required this.child,
    @required this.preferredSize,
  }) : super(key: key);

  /// The widget below this widget in the tree.
  ///
  /// {@macro flutter.widgets.child}
  final Widget child;

  @override
  final Size preferredSize;

  @override
  Widget build(BuildContext context) => child;
}

其中一個(gè)界面代碼如下颅眶,其他類似,結(jié)構(gòu)都差不多


import 'package:flutter/material.dart';
import '../models/models.dart' show PurchaseData;


class PurchasePages extends StatelessWidget {
  final _purchasedata = PurchaseData.mock().demos;
  final int _itemLength = PurchaseData.mock().demos.length;

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        itemCount: _itemLength,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            childAspectRatio: 2/1.5),
        itemBuilder: (BuildContext context,int index){
          return InkWell(
            radius: 0.0,
            highlightColor:Colors.transparent,
            onTap: _purchasedata[index].onPressed,
            child: Padding(
              padding: EdgeInsets.only(top:20),
              child: Column(
                children: <Widget>[
                  Image.asset(_purchasedata[index].avater,width: 45.0,height: 45.0,),
                  SizedBox(height: 5.0,),
                  Text(_purchasedata[index].title),
                ],
              ),
            ),
          );
        });
  }
}

模擬數(shù)據(jù)文件田弥,代碼如下涛酗。 其實(shí)這邊可以封裝一下。目前沒有做優(yōu)化,優(yōu)先把功能給先做出來商叹。

/**
 * @Author: zhouge
 * @Description:
 * @Date: Created in 15:27 2020-10-18
 * @Modified By:
 **/
import 'package:flutter/material.dart';

// 構(gòu)造函數(shù)
class BasicItem {
  final String title;
  final String avater;
  final bool isShowicon;
  final List<Widget> widget;
  final VoidCallback onPressed;

  BasicItem({
    this.isShowicon,
    this.widget,
    this.title,
    this.avater,
    this.onPressed,
  });
}

// 采購界面數(shù)據(jù)
class PurchaseData {
  final List<BasicItem> demos = [
    BasicItem(
        title: '采購收貨',
        avater: 'assets/images/icon_nocome_alllot.png',
        isShowicon: true,
        onPressed: () {
          print('采購收貨');
        }),
    BasicItem(
        title: '掃碼收貨',
        avater: 'assets/images/icon_scan_inapection.png',
        isShowicon: true,
        onPressed: () {
          print('掃碼收貨');
        }),
    BasicItem(
        title: '掃碼入庫',
        avater: 'assets/images/icon_purchase_in_store.png',
        isShowicon: true,
        onPressed: () {
          print('掃碼入庫');
        }),
    BasicItem(
        title: '采購倉退',
        avater: 'assets/images/icon_warehouse_return.png',
        isShowicon: true,
        onPressed: () {
          print('采購倉退');
        }),
    BasicItem(
        title: '來料檢驗(yàn)',
        avater: 'assets/images/icon_exceed_patch_send.png',
        isShowicon: true,
        onPressed: () {
          print('來料檢驗(yàn)');
        }),
    BasicItem(
        title: '平板檢驗(yàn)',
        avater: 'assets/images/icon_iqc_check_pad.png',
        isShowicon: true,
        onPressed: () {
          print('平板檢驗(yàn)');
        }),
    BasicItem(
        title: '快速收貨',
        avater: 'assets/images/icon_fast_receipt_goods.png',
        isShowicon: true,
        onPressed: () {
          print('快速收貨');
        }),
    BasicItem(
        title: '快速收貨',
        avater: 'assets/images/icon_srm_fast_receipt_goods.png',
        isShowicon: true,
        onPressed: () {
          print('快速收貨');
        }),
    BasicItem(
        title: '采購入庫',
        avater: 'assets/images/icon_purchase_in_ware.png',
        isShowicon: true,
        onPressed: () {
          print('采購入庫');
        }),
    BasicItem(
        title: '送貨入庫',
        avater: 'assets/images/icon_srm_scan_in_store.png',
        isShowicon: true,
        onPressed: () {
          print('送貨入庫');
        }),
  ];

  static PurchaseData mock() {
    return PurchaseData();
  }
}

大致長這個(gè)樣子的燕刻,TabBar的背景顏色和AppBar已經(jīng)區(qū)分開了

image.png

今天有空,先做到這里吧剖笙,畢竟業(yè)余時(shí)間太少卵洗,天天出差。
后面開始做功能枯途,主要涉及到接口以及掃碼功能忌怎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市酪夷,隨后出現(xiàn)的幾起案子榴啸,更是在濱河造成了極大的恐慌,老刑警劉巖晚岭,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸥印,死亡現(xiàn)場離奇詭異,居然都是意外死亡坦报,警方通過查閱死者的電腦和手機(jī)库说,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來片择,“玉大人潜的,你說我怎么就攤上這事∽止埽” “怎么了啰挪?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嘲叔。 經(jīng)常有香客問我亡呵,道長,這世上最難降的妖魔是什么硫戈? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任锰什,我火速辦了婚禮,結(jié)果婚禮上丁逝,老公的妹妹穿的比我還像新娘汁胆。我一直安慰自己,他們只是感情好霜幼,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布沦泌。 她就那樣靜靜地躺著,像睡著了一般辛掠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天萝衩,我揣著相機(jī)與錄音回挽,去河邊找鬼。 笑死猩谊,一個(gè)胖子當(dāng)著我的面吹牛千劈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牌捷,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼墙牌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了暗甥?” 一聲冷哼從身側(cè)響起喜滨,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撤防,沒想到半個(gè)月后虽风,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寄月,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年辜膝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漾肮。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厂抖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出克懊,到底是詐尸還是另有隱情忱辅,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布保檐,位于F島的核電站耕蝉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏夜只。R本人自食惡果不足惜垒在,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扔亥。 院中可真熱鬧场躯,春花似錦、人聲如沸旅挤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粘茄。三九已至签舞,卻和暖如春秕脓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背儒搭。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工吠架, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搂鲫。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓傍药,卻偏偏與公主長得像,于是被迫代替她去往敵國和親魂仍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拐辽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345