Flutter之导航栏骨架实现
  Gmus5gIMInPU 2023年11月13日 22 0


一、简介

​Flutter​​​是谷歌的移动​​UI​​​框架,可以快速在​​iOS​​​和​​Android​​上构建高质量的原生用户界面。​​Flutter​​​ 用​​Dart​​​作为开发框架和​​widget​​的语言。

二、优势

​React-Native​​​、​​Weex​​​核心是通过​​Javascript​​​开发,执行时需要​​Javascript​​​解释器,​​UI​​​是通过原生控件渲染。Flutter使用​​C​​​、​​C ++​​​、Dart和​​Skia​​​(​​2D​​​渲染引擎)构建。在​​IOS​​​上,​​Flutter​​​引擎的​​C/C ++​​​代码使用​​LLVM​​​编译,任何​​Dart​​​代码都是​​AOT​​​编译为本地代码的,​​Flutter​​​应用程序使用本机指令集运行(不涉及解释器)。而在​​Android​​​下,​​Flutter​​​引擎的​​C/C ++​​​代码是用​​Android​​​的​​NDK​​​编译的,任何​​Dart​​​代码都是​​AOT​​​编译成本地代码的,​​Flutter​​​应用程序依然使用本机指令集运行(不涉及解释器)。因此,​​Flutter​​能达到原生应用一样的性能。

三、资源网站

​Flutter​​教程网:http://www.flutterj.com/?post=47

​Flutter​​插件网站: https://pub.flutter-io.cn/

​Flutter​​中文网: https://flutterchina.club/

​Flutter​​​自带的例子:在​​Flutter​​​安装路径的​​example​​目录下就有例子,推荐学习一遍,很不错。

Flutter之导航栏骨架实现_Flutter

四、开发自己的一个​​APP​

一个通用的​​APP​​,基本上是由以下几部分组成的:

Flutter之导航栏骨架实现_AppBar_02

导航栏+内容区+底部菜单栏就是我们整个​​APP​​的骨架,其他的页面也是在这个上面去扩展。

接下来,看一下我要实现的样子:

Flutter之导航栏骨架实现_Scaffold_03

下面将一步步讲述实现过程。

4.1. 创建一个​​TabNavigator.dart​​文件

该文件是核心文件,我们的页面等页面都需要注册到里面。我们需要借助​​Scaffold​​脚手架实现这个功能。

4.1.1. 代码实现
import 'package:blog/pages/BlogPage.dart';
import 'package:blog/pages/HomePage.dart';
import 'package:blog/pages/SelfPage.dart';
import 'package:blog/pages/SourcePage.dart';
import 'package:flutter/material.dart'; // 这个是必须引入的要注意

class TabNavigator extends StatefulWidget {

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

}

class _TabNavigatorState extends State<TabNavigator> {

// 菜单栏 默认颜色和激活颜色
final _defaultColor = Colors.white;
final _activeColor = Colors.black54;

// 记录当前那个item被选中·
int _currentIndex = 0;

// 创建一个页面控制器, 并将页面的initialPage,初始为 0
final PageController _pageController = PageController(initialPage: 0);


@override
Widget build(BuildContext context) {
// 脚手架
return Scaffold(
// 在内容区使用PageView将首页等页面注册进去
body: PageView(
// 设置页面切换的方法
onPageChanged: (index) {
// setState 更新_currentIndex
setState(() {
_currentIndex = index;
});
},
controller: _pageController,
children: <Widget>[
HomePage(),
BlogPage(),
SourcePage(),
SelfPage()
],
),
// 设置底部导航栏组
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
// 设置图标,flutter的图标下面有链接
icon: Icon(Icons.home, color: _defaultColor),
// 被选中之后的图标
activeIcon: Icon(Icons.home, color: _activeColor),
// 设置文字颜色
title: Text('首页', style: TextStyle(color: _currentIndex != 0 ? _defaultColor : _activeColor))
),
BottomNavigationBarItem(
icon: Icon(Icons.event_note, color: _defaultColor),
activeIcon: Icon(Icons.event_note, color: _activeColor),
title: Text('文章', style: TextStyle(color: _currentIndex != 1 ? _defaultColor : _activeColor))
),
BottomNavigationBarItem(
icon: Icon(Icons.storage, color: _defaultColor),
activeIcon: Icon(Icons.storage, color: _activeColor),
title: Text('资源', style: TextStyle(color: _currentIndex != 2 ? _defaultColor : _activeColor))
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle, color: _defaultColor),
activeIcon: Icon(Icons.account_circle, color: _activeColor),
title: Text('我的', style: TextStyle(color: _currentIndex != 3 ? _defaultColor : _activeColor))
)
],
// 设置最初的item下标
currentIndex: _currentIndex,
// 点击之后,跳转页面,修改_currentIndex
onTap: (index) {
print(index);
_pageController.jumpToPage(index);
setState(() {
_currentIndex = index;
});
},
// 设置没有被点击也显示文字
type: BottomNavigationBarType.fixed,
// 设置背景色
backgroundColor: Colors.blue
),
);
}

}
4.1.2. ​​Scaffold​​参数详解

接下来,我们来重点介绍一下这个脚手架的一个参数(也可以查看官网文档:https://api.flutter.dev/flutter/material/Scaffold/Scaffold.html):

class Scaffold extends StatefulWidget {
/// Creates a visual scaffold for material design widgets.
const Scaffold({
Key key,
this.appBar, // 用来定义顶部导航栏
this.body, // 用来展示APP的主体部分, 主体部分大部分是通过组合Container,Column,Row,Stack来实现的
this.floatingActionButton, // 定义浮动在body右下角的组件。Flutter项目创建之后默认那个例子中就用到了这个参数。
this.floatingActionButtonLocation, // 浮动按钮放置的位置,4个枚举
this.floatingActionButtonAnimator, // 浮动按钮放置的动画
this.persistentFooterButtons, // 固定在下方显示的按钮
this.drawer, // 左侧边栏控件,就是那个像QQ一样的抽屉
this.endDrawer, // 右侧边栏控件
this.bottomNavigationBar, // 底部菜单栏,可以传入一个Flutter 提供的BottomNavigationBar来实现导航栏
this.bottomSheet, // 从底部弹出一个Widget, Flutter提供了两种方式显示,形式有点不同,一个是ModalBottomSheet, 一个是PersistentBottomSheet。
this.backgroundColor, // 背景颜色
this.resizeToAvoidBottomPadding, // 控制界面内容body是否重新布局来避免底部被覆盖了,比如当键盘显示的时候,重新布局避免被键盘盖住内容。默认值为 true, 此功能在v1.1.9之后不推荐使用。
this.resizeToAvoidBottomInset, // 如果在支架上方显示了屏幕上的键盘,则可以调整主体的大小以避免键盘重叠,这可以防止键盘遮盖主体内部的小部件。
this.primary = true, // 是否填充顶部
this.drawerDragStartBehavior = DragStartBehavior.start,
this.extendBody = false,
this.extendBodyBehindAppBar = false,
this.drawerScrimColor, // 用于在打开抽屉时遮罩背景颜色。
this.drawerEdgeDragWidth, // 水平滑动将打开抽屉的区域的宽度
}) : assert(primary != null),
assert(extendBody != null),
assert(extendBodyBehindAppBar != null),
assert(drawerDragStartBehavior != null),
super(key: key);


......
}

​Flutter​​的图标网站: https://material.io/resources/icons/?style=baseline

4.1.3. ​​PageView​​参数详解

​PageView​​​ 在​​Android​​​中也是很常用的一个控件,可以配合​​TabBar​​​、​​BottomBar​​​做页面切换。也有很多广告​​Banner​​​页用​​PageView​​​来实现。​​Flutter​​​也有这个​​Widget​​,用法更灵活方便。

PageView({
Key key,
this.scrollDirection = Axis.horizontal, // 可以控制滚动方向, 横向和纵向
this.reverse = false, // 是控制滚动方向,比如横向滚动的时候,一般我们是从右往左滚动,这个参数设置成true就是默认反一反,变成从左往右滚动。
PageController controller, // 页面控制器,可以控制跳转到某一页,可以控制PageView初始显示页面等
this.physics, // 是处理滚动到最前或滚动到最后的时候的动画效果,Flutter默认有提供几个实现好的效果,BouncingScrollPhysics、ClampingScrollPhysics等
this.pageSnapping = true, // 控制滚动方式, 默认是PageView都是一页一页翻的, 设置为false 是 PageView就可以一点点滚动,就是不用整页滚动过去,滚动到一半的时候也能停下来。
this.onPageChanged, // 监听事件,页面切换就调用一次,并传回当前显示页面的序号。
List<Widget> children = const <Widget>[], // 存放要切换的页面
this.dragStartBehavior = DragStartBehavior.start, // 处理拖动开始行为的方式。 如果设置为DragStartBehavior.start,则将在检测到拖动手势时开始滚动拖动行为。如果设置为 DragStartBehavior.down,它将在首次检测到down事件时开始。
}) : controller = controller ?? _defaultPageController,
childrenDelegate = SliverChildListDelegate(children),
super(key: key);

​PageView​​​提供了另外两种的构造方法:这种方式需要注意一点,如果不设置​​itemCount,PageView​​默认是无限个数的,也就是能一直往后翻页下去,index一直往上增加。

static var users = [
'http://xxxx',
'http://xxxx',
'http://xxxx'
]

PageView.builder(
itemBuilder: (context, index){
return Center(
child: Image.network(urls[index], fit: BoxFit.fitWidth),
);
},
itemCount: urls.length,
)

另一个方式是通过​​custom​​​,更加底层点,需要提供​​SliverChildDelegate​​,生成所有的子页面。一般使用不需要用到这个。就不上代码了。

4.2. 修改​​main.dart​

还需要修改默认的​​main.dart​​​代码,将我们的​​TabNavigator.dart​​引进去。

import 'package:blog/navigator/TabNavigator.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// 注入我们的 TabNavigator()
home: TabNavigator(),
);
}
}

4.3. 增加首页

这里首页和其他的页面一样,大同小异,只介绍​​HomePage​​,这里这个页面我们就加一个导航栏。

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();

}

class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
// 增加顶部导航栏
appBar: AppBar(
// 文字居中
centerTitle: true,
title: Text('首页')
),
// 内容区就简单加一个居中文字
body: Center(
child: Text("首页"),
),
);
}

}

这样就可以实现上面那个效果,基本上​​APP​​的骨架就搭建好了。

4.1.3. 导航栏​​AppBar​​参数详解
AppBar({
Key key,
this.leading, // 在标题前面显示的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮
this.automaticallyImplyLeading = true,
this.title, // Toolbar 中主要内容,通常显示为当前界面的标题文字
this.actions, // 一个 Widget 列表,代表 Toolbar 中所显示的菜单,对于常用的菜单,通常使用 IconButton 来表示;对于不常用的菜单通常使用 PopupMenuButton 来显示为三个点,点击后弹出二级菜单。
this.flexibleSpace,
this.bottom, // 这个小部件出现在应用程序栏的底部。 通常是一个TarBar,即一个标签栏
this.elevation,
this.shape,
this.backgroundColor, // 背景色
this.brightness, // Appbar的亮度,有白色和黑色两种主题,默认ThemeData.primaryColorBrightness
this.iconTheme, // icon主题设置
this.actionsIconTheme, // 选中icon主题
this.textTheme, // 文本主题设置
this.primary = true, // 是否显示在任务栏顶部
this.centerTitle, // 标题是否居中显示
this.titleSpacing = NavigationToolbar.kMiddleSpacing, // 横轴上围绕title内容的间距 0.0即占据所有有用空间
this.toolbarOpacity = 1.0, // 应用程序栏的工具栏的透明程度。值1.0是完全不透明的,值0.0是完全透明的
this.bottomOpacity = 1.0, // appBar底部透明度,设置方式同toolbarOpacity
}) : assert(automaticallyImplyLeading != null),
assert(elevation == null || elevation >= 0.0),
assert(primary != null),
assert(titleSpacing != null),
assert(toolbarOpacity != null),
assert(bottomOpacity != null),
preferredSize = Size.fromHeight(kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0)),
super(key: key);


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  b1UHV4WKBb2S   2023年11月13日   33   0   0 裁剪ideflutter
  b1UHV4WKBb2S   2023年11月13日   26   0   0 flutterDart
Gmus5gIMInPU