首页 > 其他分享 >Flutter之导航栏骨架实现

Flutter之导航栏骨架实现

时间:2022-12-19 14:01:10浏览次数:48  
标签:PageView color 骨架 dart currentIndex 导航 Flutter 页面


一、简介

​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之导航栏骨架实现_flutter_02

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

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

Flutter之导航栏骨架实现_flutter_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);


标签:PageView,color,骨架,dart,currentIndex,导航,Flutter,页面
From: https://blog.51cto.com/luckyqilin/5952266

相关文章

  • Flutter和Rust如何优雅的交互
    前言​​文章的图片链接都是在github上,可能需要...你懂得;本文含有大量关键步骤配置图片,强烈建议在合适环境下阅读​​Flutter直接调用C层还是蛮有魅力,想想你练习C++,然后直接......
  • 西北师范大学-校园导航系统
    摘    要本课程设计实例在给出校园各主要建筑的名称信息及有路线连通的建筑物之间的距离的基础上,利用校园导航系统计算出给定的起点到终点之间的距离最近的行进路......
  • vue2 路由24 声明式导航 编程式导航 路由守卫
    用户点击了页面的路由链接,会导致hash值发生变化,路由监听到hash值的链接发生的变化,会把对应的组件渲染到当前的页面中   安装:直接安装router的话会安装最新版的,最新......
  • 我的网址导航
    谷歌 Youtube 和B站一样有一些教学视频,Python,数学等等FaceBookTwitter......
  • Android实现导航菜单左右滑动效果
    本文给大家介绍在Android中如何实现顶部导航菜单左右滑动效果。今天给大家介绍在Android中实现顶部导航菜单左右滑动效果的二种解决方案。第一种解决方案: 然使and......
  • flutter 对dio进行简单的二次封装
    前言:在项目中,我们往往要对第三方框架进行二次封装,目的在于减小项目对第三方框架的依赖下载所需要的依赖,文件pubspec.yamldependencies:dio:^4.0.6//http请求依赖......
  • 【Android -- 开源库】那些酷炫的WheelPicker & 导航栏开源库整理
    不断学习,做更好的自己!......
  • 自定义导航栏
    UI对于导航栏有一些自己的想法,需要导航栏高度变高,需要加载Gif,需要按钮图标凸起,所以原本的导航栏就满足不了需求了,我们需要自定义UITabBar自定义导航栏......
  • 浙大团队利用机器人导航系统提高脑机接口植入手术成功率
    与非植入式脑机接口(BCI)相比,植入式BCI可通过微电极的细胞外记录检测单个神经元的信号,植入的微电极越多,采集到的神经元就信号就越多,对应的空间和时间分辨率就越高,能够实现精确......
  • Blazor和Vue对比学习(进阶.路由导航五):路由守卫
    路由守卫,可以认为是设置在导航源和目标之间的中间件。Vue在代码上,表现为命名约定的钩子(类似于生命周期钩子),而Blazor会更复杂一些。VueRouter的路由守卫功能非常完善,而Blaz......