好久没在简书写东西了,基本上自己的笔记都写在印象上去了。这次分享flutter呢,是记录一下自己用flutter做的第一个app. 首先这个app没有flutter的知识讲解,只是简单的记录一下自己这个app完成的过程。 推荐大家学习flutter可以去 技术胖学习。
项目git地址:flower_gift
app框架搭建 - 2019-07-26
app首页:
1.创建app
2.创建app开发相关文件夹
lib文件夹下创建:
config :基本配置文件,如url地址等
model :数据模型
pages :界面文件
provide :数据交互
routers :路由文件
service :网络请求方法
- tabBar文件编写:
import "package:flutter/material.dart";
import 'package:flutter/cupertino.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';//界面适配插件
import './home_page.dart';
import './category_page.dart';
import './flower_find_page.dart';
import './car_shop_page.dart';
import './mine_page.dart';
import 'package:provide/provide.dart'; //数据交互插件
import '../provide/tabBarTap_provide.dart'; //tabBar Provide文件
class TabBarPage extends StatelessWidget {
//tabBar子界面
final List<BottomNavigationBarItem> bottomTabs = [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
title: Text("首页")
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.collections),
title: Text("分类")
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.share),
title: Text("花现")
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.shopping_cart),
title: Text("购物车")
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.profile_circled),
title: Text("我的")
),
];
//对应的tabBar子页面
final List<Widget> tabBarSubPages = [
HomePage(),
CategoryPage(),
FlowerFindPage(),
CarShopPage(),
MinePage()
];
@override
Widget build(BuildContext context) {
//界面适配
ScreenUtil.instance = ScreenUtil(width: 750.0,height: 1334.0)..init(context);//给定初始尺寸,也就是基本尺寸,其余的都在此基础上缩放
return Scaffold(
backgroundColor: Colors.white,
bottomNavigationBar: Provide<TabBarTapProvide>(
builder: (context,child,tabBarTap){
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: tabBarTap.currentTabIndex,
fixedColor: Color.fromRGBO(255, 95, 63, 1.0),
items: bottomTabs,
onTap: (index){
Provide.value<TabBarTapProvide>(context).bottomTabBarTap(index);
},
);
},
),
body: Provide<TabBarTapProvide>(
builder: (context,child,tabBarTap){
return IndexedStack(
index: tabBarTap.currentTabIndex,
children: tabBarSubPages,
);
},
)
);
}
}
tabBar Provide 文件:
import 'package:flutter/widgets.dart';
class TabBarTapProvide with ChangeNotifier{
int currentTabIndex = 0;
bottomTabBarTap(tapIndex){
currentTabIndex = tapIndex;
//通知
notifyListeners();
}
}
通过provide来控制这个数据的变化,从而控制界面变化。尤其是在完全不相关的多个widget之间的数据交互。 除了编写对应的provide文件外,还需要在main.dart中注册。 用provide控制数据变化,比用StatefulWidget状态组件要方便得多
- 首页:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';//iOS风格UI
import './pages/tabBar_page.dart';
import 'package:provide/provide.dart';//状态管理
import './provide/tabBarTap_provide.dart';//底部tab点击状态管理
void main() {
var providers = Providers();
var tabBarTapProvide = TabBarTapProvide();
//状态管理注册
providers
..provide(Provider<TabBarTapProvide>.value(tabBarTapProvide));
runApp(
ProviderNode(
child: MyApp(),
providers: providers,
)
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return Container(
child: MaterialApp(
title: "花礼网",
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color.fromRGBO(45, 60, 49, 1.0),//主题色
),
home: TabBarPage(),
),
);
}
}
首页主要就看看这个provide注册
5.各个子界面:
5.1: homePage.dart
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../service/service_http_method.dart';
import 'dart:convert';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
_getHomePageData();
return Scaffold(
appBar: AppBar(
title: Text("花礼网",
style: TextStyle(
color: Color.fromRGBO(255, 95, 63, 1.0),
fontSize: ScreenUtil().setSp(45.0)
),
),
),
body:Container(
child: Center(
child: Text("我是首页"),
),
)
);
}
void _getHomePageData(){
requestGet("shouye").then((val){
var data = json.decode(val.toString());
print("获取首页数据成功:${data}");
});
}
}
给homePage页面加上了导航栏,其次进行了首页数据请求的测试。
5.2: category.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Text("我是分类"),
),
);
}
}
其它三个界面只是标题不一样。
6.网络请求配置:
config/service_url_config.dart
const baseServiceUrl = "https://fbz.dbhome.com/";(不是真实接口地址,怕放上来侵权,也不懂。。。)
const requestUrl = {
"shouye":baseServiceUrl + "shouye/v3",//首页数据请求
"itemList":baseServiceUrl + "itemlist/list",//分类页面
};
service/service_http_method.dart
import 'package:dio/dio.dart';
import 'dart:async';
import 'dart:io';
import '../config/service_url_config.dart';
//抽取公共的网络请求方法
Future requestGet(url,{formData}) async{
try{
print("开始获取网络数据...");
Response response;
Dio dio = new Dio();
dio.options.responseType = ResponseType.plain;//不整这个就会报Unexpected character错误
dio.options.contentType = ContentType.parse("application/x-www-form-urlencoded");
if(formData == null){
//无参
response = await dio.post(requestUrl[url]);
}else{
response = await dio.post(requestUrl[url],data:formData);
}
if(response.statusCode == 200){
return response.data;
}else{
throw Exception("<<<<<<请求失败,检查接口或者参数>>>>>>");
}
}catch(e){
return print("HTTPERROR: ============> ${e}");
}
}
最后R 加载,数据请求成功,最后效果: