玖叶教程网

前端编程开发入门

Flutter快速实现APP首页操作按钮,源码直接拿去用,Android,IOS

本头条核心宗旨

欢迎来到技术刚刚好头条,本头条是个人维护,每天至少更新一篇Flutter技术文章,实时为大家播报Flutter最新消息。如果你刚好也在关注Flutter这门技术,那就跟我一起学习进步吧,你的赞,收藏,转发是对我个人最大的支持,维护不易,欢迎关注。

技术刚刚好经历

近几年,移动端跨平台开发技术层出不穷,从Facebook家的ReactNative,到阿里家WEEX,前端技术在移动端跨平台开发中大展身手,技术刚刚好作为一名Android开发,经历了从Reactjs到Vuejs的不断学习。而在2018年,我们的主角变成了Flutter,这是Goolge开源的一个移动端跨平台解决方案,可以快速开发精美的移动App。希望跟大家一起学习,一起进步!

本篇文章中心思想

很高兴,大家早上好,每天醒来要做到第一件事情就是写文章,今天我们要实现到主要内容有如下技术点:StatelessWidget,Scaffold,appBarContainer,ListViewitemBuilderBottomNavigationBar。每一个都是Flutter到技术点,我相信大家看到这些方法并不陌生,因为之前到文章都有说到,效果图如下,很简单到设计,基本小到APP也就这个结构吧,底部一个操作栏,点击进入每个页面,然后处理了返回按钮逻辑,进入详情页面,双击底部按钮返回到首页。我会把所有代码都贴出来,大家复制可以直接使用。

看看整体到项目结构图吧

main.dart文件到讲解

这个文件很简单,正常到一个启动文件,运用到了StatelessWidget框架。和MaterialApp效果。

import 'package:flutter/material.dart';
import 'package:nested_navigation_demo_flutter/app.dart';

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

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 title: 'Flutter Demo',
 theme: ThemeData(
 primarySwatch: Colors.blue,
 ),
 home: App(),
 );
 }
}

App.dart文件介绍

这个文件头部导入包,代码里面也有注释,大家可以自己看看。

import 'package:flutter/material.dart';
import 'package:nested_navigation_demo_flutter/bottom_navigation.dart';
import 'package:nested_navigation_demo_flutter/tab_navigator.dart';

//APP首页显示
class App extends StatefulWidget {
 //创建一个有状态到组件
 @override
 State<StatefulWidget> createState() => AppState();
}


class AppState extends State<App> {
 //tab到item栏目,定义到枚举类型
 TabItem _currentTab = TabItem.red;

 //页面
 Map<TabItem, GlobalKey<NavigatorState>> _navigatorKeys = {
 TabItem.red: GlobalKey<NavigatorState>(),
 TabItem.green: GlobalKey<NavigatorState>(),
 TabItem.blue: GlobalKey<NavigatorState>(),
 };

 //选中到栏目
 void _selectTab(TabItem tabItem) {
 if (tabItem == _currentTab) {
 // pop to first route
 _navigatorKeys[tabItem].currentState.popUntil((route) => route.isFirst);
 } else {
 setState(() => _currentTab = tabItem);
 }
 }



 @override
 Widget build(BuildContext context) {

 //导航返回拦截处理
 return WillPopScope(
 //是一个回调函数,当用户点击返回按钮时被调用
 onWillPop: () async {//async关键字声明该函数内部有代码需要延迟执行
 //但是要使用await,必须在有async标记的函数中运行,否则这个await会报错:
 final isFirstRouteInCurrentTab =
 !await _navigatorKeys[_currentTab].currentState.maybePop();
 if (isFirstRouteInCurrentTab) {
 // 如果不在“主要”标签上
 if (_currentTab != TabItem.red) {
 // 选择“主”标签
 _selectTab(TabItem.red);
 // 由应用程序处理的后退按钮
 return false;
 }
 }
 // 如果我们在第一条路线上,让系统处理后退按钮
 return isFirstRouteInCurrentTab;
 },
 child: Scaffold(
 body: Stack(children: <Widget>[
 _buildOffstageNavigator(TabItem.red),
 _buildOffstageNavigator(TabItem.green),
 _buildOffstageNavigator(TabItem.blue),
 ]),
 bottomNavigationBar: BottomNavigation(
 currentTab: _currentTab,
 onSelectTab: _selectTab,
 ),
 ),
 );
 }

 Widget _buildOffstageNavigator(TabItem tabItem) {
 return Offstage(
 offstage: _currentTab != tabItem,
 child: TabNavigator(
 navigatorKey: _navigatorKeys[tabItem],
 tabItem: tabItem,
 ),
 );
 }
}

bottom_navigation.dart文件介绍

import 'package:flutter/material.dart';

enum TabItem { red, green, blue }

//底部按钮
Map<TabItem, String> tabName = {
 TabItem.red: 'red',
 TabItem.green: 'green',
 TabItem.blue: 'blue',
};

//map集合
Map<TabItem, MaterialColor> activeTabColor = {
 TabItem.red: Colors.red,
 TabItem.green: Colors.green,
 TabItem.blue: Colors.blue,
};

class BottomNavigation extends StatelessWidget {
 BottomNavigation({this.currentTab, this.onSelectTab});
 final TabItem currentTab;
 final ValueChanged<TabItem> onSelectTab;

 @override
 Widget build(BuildContext context) {
 //BottomNavigationBar组件
 return BottomNavigationBar(
 type: BottomNavigationBarType.fixed,
 items: [
 _buildItem(tabItem: TabItem.red),
 _buildItem(tabItem: TabItem.green),
 _buildItem(tabItem: TabItem.blue),
 ],
 onTap: (index) => onSelectTab(
 TabItem.values[index],
 ),
 );
 }

 BottomNavigationBarItem _buildItem({TabItem tabItem}) {
 String text = tabName[tabItem];
 IconData icon = Icons.layers;
 return BottomNavigationBarItem(
 icon: Icon(
 icon,
 color: _colorTabMatching(item: tabItem),
 ),
 title: Text(
 text,
 style: TextStyle(
 color: _colorTabMatching(item: tabItem),
 ),
 ),
 );
 }

 Color _colorTabMatching({TabItem item}) {
 return currentTab == item ? activeTabColor[item] : Colors.grey;
 }
}

详情页面到介绍color_detail_page.dart

import 'package:flutter/material.dart';
//详情页面
class ColorDetailPage extends StatelessWidget {
 ColorDetailPage({this.color, this.title, this.materialIndex: 500});
 final MaterialColor color;
 final String title;
 final int materialIndex;

 @override
 Widget build(BuildContext context) {

 return Scaffold(
 appBar: AppBar(
 backgroundColor: color,
 title: Text(
 '$title[$materialIndex]',
 ),
 ),
 body: Container(
 color: color[materialIndex],
 ),
 );
 }
}

列表效果colors_list_page.dart

import 'package:flutter/material.dart';

class ColorsListPage extends StatelessWidget {
 ColorsListPage({this.color, this.title, this.onPush});
 final MaterialColor color;
 final String title;
 final ValueChanged<int> onPush;

 @override
 Widget build(BuildContext context) {

 //脚手架
 return Scaffold(
 //标题栏
 appBar: AppBar(
 title: Text(
 title,
 ),
 backgroundColor: color,
 ),
 //内容Container是一个组合类容器
 body: Container(
 color: Colors.white,
 child: _buildList(),
 ));
 }

 final List<int> materialIndices = [900, 800, 700, 600, 500, 400, 300, 200, 100, 50];

 Widget _buildList() {

 //ListView就是我们常见的列表组件
 return ListView.builder(
 //item数量
 itemCount: materialIndices.length,
 //item构建者
 itemBuilder: (BuildContext content, int index) {
 int materialIndex = materialIndices[index];
 //内容Container是一个组合类容器
 return Container(
 color: color[materialIndex],
 child: ListTile(
 title: Text('$materialIndex', style: TextStyle(fontSize: 24.0)),
 trailing: Icon(Icons.chevron_right),
 onTap: () => onPush(materialIndex),
 ),
 );
 });
 }
}

路由页面tab_navigator.dart

import 'package:flutter/material.dart';
import 'package:nested_navigation_demo_flutter/bottom_navigation.dart';
import 'package:nested_navigation_demo_flutter/color_detail_page.dart';
import 'package:nested_navigation_demo_flutter/colors_list_page.dart';

//路由页面
class TabNavigatorRoutes {
 static const String root = '/';
 static const String detail = '/detail';
}

class TabNavigator extends StatelessWidget {
 TabNavigator({this.navigatorKey, this.tabItem});
 final GlobalKey<NavigatorState> navigatorKey;
 final TabItem tabItem;

 void _push(BuildContext context, {int materialIndex: 500}) {
 var routeBuilders = _routeBuilders(context, materialIndex: materialIndex);

 Navigator.push(
 context,
 MaterialPageRoute(
 builder: (context) => routeBuilders[TabNavigatorRoutes.detail](context),
 ),
 );
 }

 Map<String, WidgetBuilder> _routeBuilders(BuildContext context,
 {int materialIndex: 500}) {
 return {
 TabNavigatorRoutes.root: (context) => ColorsListPage(
 color: activeTabColor[tabItem],
 title: tabName[tabItem],
 onPush: (materialIndex) =>
 _push(context, materialIndex: materialIndex),
 ),
 TabNavigatorRoutes.detail: (context) => ColorDetailPage(
 color: activeTabColor[tabItem],
 title: tabName[tabItem],
 materialIndex: materialIndex,
 ),
 };
 }

 @override
 Widget build(BuildContext context) {
 final routeBuilders = _routeBuilders(context);
 return Navigator(
 key: navigatorKey,
 initialRoute: TabNavigatorRoutes.root,
 onGenerateRoute: (routeSettings) {
 return MaterialPageRoute(
 builder: (context) => routeBuilders[routeSettings.name](context),
 );
 },
 );
 }
}

总结

希望大家能够希望本头条,本头条坚持写Flutter语言到DEMO和API到学习笔记。

谢谢观看技术刚刚好头条文章,本头条是个人维护,每天至少更新一篇Flutter技术文章,实时为大家播报Flutter最新消息。如果你刚好也在关注Flutter这门技术,那就跟我一起学习进步吧,你的赞,收藏,转发是对我个人最大的支持,维护不易,欢迎关注。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言