Flutter

【Flutter】TabBar 改背景色

2020-10-18  本文已影响0人  jiandanyaobai

之前有提过要仿公司 某款产品的UI,用Flutter刚好试试手。首页登陆都做了,有几个坑记录一下。
这里展示的功能其实都应该从后端获取的,后端这一块目前没做,后面有空了补起来。
相对比较简单,主要涉及到以下几点:
1、TabBar上无法设置颜色和高度,标准库默认与AppBar颜色一致。
2、GridView的基本运用。

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))
                ]),
              ),

              //可以单独设置,固定高度为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('生产管理'),
                        Text('仓库管理'),
                        Text('销售管理'),
                    ],
                  ),
                )
              )),
          body: Container(
            color: Colors.white,
            child: TabBarView(
              children: <Widget>[
                PurchasePages(),
                WorkPages(),
                WareHousePages(),
                SalesPages(),
              ],
            ),
          )
        ));
  }
}

这里的bottom下没有直接TabBar,而且用PreferredSize来进行取代。如果直接用TabBar的话,颜色会与顶部一致,并且无法更改。

这里可以看到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,点进去看下,经过观察,我们可以使用它重新布局画面。

记住一定要在Material下,单独设置颜色

// 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;
}

其中一个界面代码如下,其他类似,结构都差不多


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),
                ],
              ),
            ),
          );
        });
  }
}

模拟数据文件,代码如下。 其实这边可以封装一下。目前没有做优化,优先把功能给先做出来。

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

// 构造函数
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,
  });
}

// 采购界面数据
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: '来料检验',
        avater: 'assets/images/icon_exceed_patch_send.png',
        isShowicon: true,
        onPressed: () {
          print('来料检验');
        }),
    BasicItem(
        title: '平板检验',
        avater: 'assets/images/icon_iqc_check_pad.png',
        isShowicon: true,
        onPressed: () {
          print('平板检验');
        }),
    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();
  }
}

大致长这个样子的,TabBar的背景颜色和AppBar已经区分开了

image.png

今天有空,先做到这里吧,毕竟业余时间太少,天天出差。
后面开始做功能,主要涉及到接口以及扫码功能。

上一篇下一篇

猜你喜欢

热点阅读