Flutter入门系列-Widget系列二-容器Widget

1. Stack 层叠布局

 Container(
    color: Colors.grey,
    margin: EdgeInsets.only(left: 10, right: 10),
    height: 100,
    child: Stack(
        children: [
        Positioned(
            // Positioned用于嵌套于Stack容器,确定Positioned的布局到父容器四角的位置
            child: Image.asset(
            'images/lovely_girl.jpg',
            width: 200.0,
            fit: BoxFit.cover,
            ),
            left: 10.0,
            top: 20.0,
        ),
        Positioned(
            left: 10,
            top: 20,
            child: Text(
            'Android进阶三步曲',
            style: TextStyle(color: Colors.lightBlue, fontSize: 20),
            ),
        )
        ],
    ),
)

2. Wrap 流式布局

Padding(
    padding: EdgeInsets.all(0.0),
    child: Wrap(
        direction: Axis.horizontal, //主轴的方向
        spacing: 4.0, //主轴方向的条目间距
        runSpacing: -8.0, //副轴方向的条目间距
        children: [
        Chip(
            label: Text('Android'),
        ),
        Chip(
            label: Text('iOS'),
        ),
        Chip(
            label: Text('Flutter'),
        ),
        Chip(
            label: Text('Kotlin'),
        ),
        Chip(
            label: Text('Kotlin'),
        ),
        Chip(
            label: Text('Kotlin'),
        )
        ],
    ),
),

3. 抽屉布局

class _HomeDrawerPageState extends State<HomeDrawerPage> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
       debugShowCheckedModeBanner: false,
       theme: ThemeData(primaryColor: Colors.blue),
       home: Scaffold(
           appBar: AppBar(title: Text('抽屉布局'),),
           body: Container(
             child: Center(
               child: Text('我的页面'),
             ),
           ),
           drawer: DrawerSidePage() ,
       ),
    );
  }
}

4. Flex 布局

//Flutter中的弹性布局是Flex, 类似于Android中的FlexboxLayout。
//为了避免子Widget在Flex, Row, Column中超界,可以使用Flexible和Expanded,
//它们可以使Flex, Row, Column的子Widget具有弹性能力。
class CommonFlexPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
       appBar: AppBar(title: Text('弹性布局'),),
       body: Flex(
          direction: Axis.horizontal,
          children: [
            Expanded(
              flex: 1,
              child: Container(height: 60.0, color: Colors.red,)),
            Expanded(
              flex: 3, 
              child: Container(height: 60.0, color: Colors.blue,)),
            Expanded(
              flex: 2,
              child: Container(height: 60.0, color: Colors.green,)),
          ],
       ),
    );
  }
}

4. BottomNavigationBar+ PageView 类微信底部页面切换

import 'package:flutter/material.dart';
import 'package:flutter_widgets/layout/keep_alive_list.dart';

//TabBar+PageView用于构建底部TabBar+PageView的页面,常用于主页显示,类似微信这种主页
class TabBarPageNewView extends StatefulWidget {
  @override
  _TabBarPageViewState createState() => _TabBarPageViewState();
}

class _TabBarPageViewState extends State<TabBarPageNewView>
    with TickerProviderStateMixin {
  PageController _pageController;
  final _defaultColor = Colors.grey;
  final _activeColor = Colors.blue;
  int _currentIndex = 0;

  @override
  void initState() {
    super.initState();
    _pageController = PageController(initialPage: 0);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PageView+TabBar页面'),
      ),
      body: new PageView(
        controller: _pageController,
        physics: NeverScrollableScrollPhysics(),
        children: <Widget>[
          KeepAliveList(
            title: '首页',
          ),
          KeepAliveList(
            title: '搜索',
          ),
          KeepAliveList(
            title: '旅拍',
          ),
          KeepAliveList(
            title: '我的',
          ),
        ],
      ),
      bottomNavigationBar: _getBottomTabBarByType(),
    );
  }

  //返回底部Tab
  Widget _getBottomTabBarByType() {
    return BottomNavigationBar(
      items: [
        BottomNavigationBarItem(
          icon: Icon(
            Icons.home,
            color: _defaultColor,
          ),
          activeIcon: Icon(
            Icons.home,
            color: _activeColor,
          ),
          // ignore: deprecated_member_use
          title: Text(
            '首页',
            style: TextStyle(
                color: _currentIndex != 0 ? _defaultColor : _activeColor),
          ),
        ),
        BottomNavigationBarItem(
          icon: Icon(
            Icons.search,
            color: _defaultColor,
          ),
          activeIcon: Icon(
            Icons.search,
            color: _activeColor,
          ),
          // ignore: deprecated_member_use
          title: Text(
            '搜索',
            style: TextStyle(
                color: _currentIndex != 1 ? _defaultColor : _activeColor),
          ),
        ),
        BottomNavigationBarItem(
          icon: Icon(
            Icons.camera_alt,
            color: _defaultColor,
          ),
          activeIcon: Icon(
            Icons.camera_alt,
            color: _activeColor,
          ),
          // ignore: deprecated_member_use
          title: Text(
            '旅拍',
            style: TextStyle(
                color: _currentIndex != 2 ? _defaultColor : _activeColor),
          ),
        ),
        BottomNavigationBarItem(
          icon: Icon(
            Icons.account_circle,
            color: _defaultColor,
          ),
          activeIcon: Icon(
            Icons.account_circle,
            color: _activeColor,
          ),
          // ignore: deprecated_member_use
          title: Text(
            '我的',
            style: TextStyle(
                color: _currentIndex != 3 ? _defaultColor : _activeColor),
          ),
        ),
      ],
      currentIndex: _currentIndex,
      onTap: (index) {
        _pageController.jumpToPage(index);
        setState(() {
          _currentIndex = index;
        });
      },
      type: BottomNavigationBarType.fixed, // label 永远显示
    );
  }

  @override
  void dispose() {
    super.dispose();
    _pageController.dispose();
  }
}
import 'package:flutter/material.dart';

class KeepAliveList extends StatefulWidget {
  final String title;

  KeepAliveList({Key key, this.title}) : super(key: key);

  @override
  _KeepAliveListState createState() => _KeepAliveListState(title);
}

class _KeepAliveListState extends State<KeepAliveList>
    with AutomaticKeepAliveClientMixin {
  var title;

  _KeepAliveListState(String title) {
    this.title = title;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Container(
      child: RefreshIndicator(
        onRefresh: _handleOnRefresh,
        child: ListView.builder(
            physics: const AlwaysScrollableScrollPhysics(),
            itemCount: 20,
            itemBuilder: (context, index) {
              return Container(
                width: double.infinity,
                height: 40,
                margin: EdgeInsets.fromLTRB(10, 5, 10, 5),
                alignment: Alignment.center,
                color: Colors.blue,
                child: Text(
                  '$title $index',
                  style: TextStyle(color: Colors.white),
                ),
              );
            }),
      ),
    );
  }

  Future<Null> _handleOnRefresh() async {
    await Future.delayed(Duration(seconds: 2));
    return null;
  }

  @override
  bool get wantKeepAlive => true; //保存页面状态
  
}

5. 顶部Tab+PageView 类似头条顶部分类显示

注意:如果不实现AutoKeepAliveClientMixin接口,那么就会出现再次返回列表之后,列表会自动的滑动到第一项,也就是说页面的状态无法保持住,所以为了保持页面状态,要实现这个接口,并将 wantKeepAlive 方法返回 true, 其次,还要将 build() 方法中的第一行调用 super.build(context);

import 'package:flutter/material.dart';
import 'package:flutter_widgets/layout/keep_alive_list.dart';

//顶部TabBar+TabBarView 组成的页面
class TabBarTabBarViewPage extends StatefulWidget {
  @override
  _TabBarTabBarViewPageState createState() => _TabBarTabBarViewPageState();
}

class _TabBarTabBarViewPageState extends State<TabBarTabBarViewPage>
    with TickerProviderStateMixin {
  TabController _tabController;
  List<String> myTabs = [
    'Kotlin',
    'Flutter',
    'C',
    'C++',
    'Android',
    'Flutter',
    'iOS '
  ];

  @override
  void initState() {
    super.initState();
    _tabController = new TabController(length: myTabs.length, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false, // 取消向左的箭头
        title: TabBar(
          isScrollable: true,
          controller: _tabController,
          tabs: myTabs
              .map((title) => Tab(
                    text: title,
                  ))
              .toList(),
          indicatorColor: Colors.blue,
          indicatorWeight: 4.0, // indicator的宽度
          //automaticIndicatorColorAdjustment: true,
          indicatorPadding: EdgeInsets.zero,
          indicatorSize: TabBarIndicatorSize.tab, // indicator的长度 .tab是等分宽度 .label是和名字一样宽
        ),
      ),
      body: TabBarView(
          controller: _tabController,
          children: myTabs.map((item) => KeepAliveList(title: item)).toList()),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _tabController.dispose();
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值