dio
- dio: 网络请求
import 'package:flutter/material.dart';
import './routers/routers.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: const AppBarTheme(
centerTitle: true,
)
),
initialRoute: "/",
onGenerateRoute: onGenerateRoute,
);
}
}
import 'package:flutter/cupertino.dart';
import '../pages/tabs.dart';
import '../pages/jsonMap.dart';
import '../pages/dio.dart';
import '../pages/dioGetCategory.dart';
import '../pages/dioAndFutureBuilderGetCategory.dart';
import '../pages/news.dart';
//1、配置路由
Map routes = {
"/": (contxt) => const Tabs(),
"/jsonMap": (contxt) => const JsonMapPage(),
"/dio": (contxt) => const DioPage(),
"/dioGetCategory": (contxt) => const DioGetCategoryPage(),
"/dioAndFutureBuilderGetCategory": (contxt) =>
const DioAndFutureBuilderGetCategory(),
"/news": (contxt) => const NewsPage(),
};
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // /news 或者 /search
final Function? pageContentBuilder =
routes[name]; // Function = (contxt) { return const NewsPage()}
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
import 'package:flutter/material.dart';
import './tabs/home.dart';
import './tabs/category.dart';
import './tabs/message.dart';
import './tabs/setting.dart';
import './tabs/user.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({super.key, this.index = 0});
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
void initState() {
// TODO: implement initState
super.initState();
_currentIndex = widget.index;
}
final List<Widget> _pages = const [
HomePage(),
CategoryPage(),
MessagePage(),
SettingPage(),
UserPage()
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
drawer: Drawer(
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: UserAccountsDrawerHeader(
accountName: const Text("itying"),
accountEmail: const Text("itying@qq.com"),
otherAccountsPictures: [
Image.network(
"https://www.itying.com/images/flutter/1.png"),
Image.network(
"https://www.itying.com/images/flutter/2.png"),
Image.network(
"https://www.itying.com/images/flutter/3.png"),
],
currentAccountPicture: const CircleAvatar(
backgroundImage: NetworkImage(
"https://www.itying.com/images/flutter/3.png")),
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://www.itying.com/images/flutter/2.png"))),
))
],
),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.people),
),
title: Text("个人中心"),
),
const Divider(),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.settings),
),
title: Text("系统设置"),
),
const Divider(),
],
),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red, //选中的颜色
// iconSize:35, //底部菜单大小
currentIndex: _currentIndex, //第几个菜单选中
type: BottomNavigationBarType.fixed, //如果底部有4个或者4个以上的菜单的时候就需要配置这个参数
onTap: (index) {
//点击菜单触发的方法
//注意
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),
BottomNavigationBarItem(icon: Icon(Icons.message), label: "消息"),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),
BottomNavigationBarItem(icon: Icon(Icons.people), label: "用户")
]),
floatingActionButton: Container(
height: 60, //调整FloatingActionButton的大小
width: 60,
padding: const EdgeInsets.all(5),
margin: const EdgeInsets.only(top: 5), //调整FloatingActionButton的位置
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30),
),
child: FloatingActionButton(
backgroundColor: _currentIndex == 2 ? Colors.red : Colors.blue,
child: const Icon(Icons.add),
onPressed: () {
setState(() {
_currentIndex = 2;
});
}),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked, //配置浮动按钮的位置
);
}
}
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/jsonMap");
},
child: const Text("jsonMap转换演示")),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/dio");
},
child: const Text("Dio请求数据")),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/dioGetCategory");
},
child: const Text("获取分类数据")),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/dioAndFutureBuilderGetCategory");
},
child: const Text("Dio结合FutureBuilder渲染数据")),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/news");
},
child: const Text("新闻页面 下拉加载 上拉分页")),
],
),
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
class JsonMapPage extends StatefulWidget {
const JsonMapPage({super.key});
State<JsonMapPage> createState() => _JsonMapPageState();
}
class _JsonMapPageState extends State<JsonMapPage> {
void initState() {
// TODO: implement initState
super.initState();
//1、Map转换成Json字符串
// Map userInfo = {"username": "张三", "age": 20};
// print(userInfo["username"]);
// String str = json.encode(userInfo);
// print(str);
//2、Json字符串转换成Map
String str = '{"username":"张三","age":20}';
Map userInfo = json.decode(str);
print(userInfo is Map);
print(userInfo);
print(userInfo["username"]);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('JsonMap'),
),
body: const Center(
child: Text(" JSON字符串和Map类型的转换"),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class DioPage extends StatefulWidget {
const DioPage({super.key});
State<DioPage> createState() => _DioPageState();
}
class _DioPageState extends State<DioPage> {
//Restful Api中 get主要用于获取数据
_getData() async {
var response = await Dio().get("https://jdmall.itying.com/api/httpGet",
queryParameters: {"username": "张三", "age": 20});
print(response.data);
print(response.data is Map);
print(response.data["msg"]);
}
//Restful Api中 post主要用于提交数据 增加数据
_postData() async {
var response = await Dio().post("https://jdmall.itying.com/api/httpPost",
data: {"username": "张三", "address": "北京"});
print(response.data);
print(response.data is Map);
print(response.data["msg"]);
}
//Restful Api中 put请求主要用于更新数据
_putData() async {
var response = await Dio().put("https://jdmall.itying.com/api/httpPut",
data: {"id": "123", "username": "张三", "address": "北京"});
print(response.data);
print(response.data is Map);
print(response.data["msg"]);
}
//Restful Api中 delete请求主要用于删除数据
_deleteData() async {
var response = await Dio().delete(
"https://jdmall.itying.com/api/httpDelete",
queryParameters: {"id": "123"});
print(response.data);
print(response.data is Map);
print(response.data["msg"]);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _getData,
child: const Text('Get请求数据'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _postData,
child: const Text('Post提交数据'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _putData,
child: const Text('Put修改数据'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _deleteData,
child: const Text('删除数据'),
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class DioGetCategoryPage extends StatefulWidget {
const DioGetCategoryPage({super.key});
State<DioGetCategoryPage> createState() => _DioGetCategoryPageState();
}
class _DioGetCategoryPageState extends State<DioGetCategoryPage> {
List _list = [];
void initState() {
super.initState();
_getData();
}
_getData() async {
var response = await Dio().get("https://jdmall.itying.com/api/pcate");
print(response.data);
print(response.data["result"] is List);
print(response.data["result"][0]["title"]);
setState(() {
_list = response.data["result"];
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: _list.isNotEmpty
? ListView(
children: _list.map(
(value) {
return Column(
children: [
ListTile(
title: Text("${value["title"]}"),
),
const Divider()
],
);
},
).toList(),
)
: const Center(
child: CircularProgressIndicator(),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class DioAndFutureBuilderGetCategory extends StatefulWidget {
const DioAndFutureBuilderGetCategory({super.key});
State<DioAndFutureBuilderGetCategory> createState() =>
_DioAndFutureBuilderGetCategoryState();
}
class _DioAndFutureBuilderGetCategoryState
extends State<DioAndFutureBuilderGetCategory> {
Future<List> _getData() async {
var response = await Dio().get("https://jdmall.itying.com/api/pcate");
print(response.data);
print(response.data["result"] is List);
print(response.data["result"][0]["title"]);
return response.data["result"];
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: FutureBuilder(
future: _getData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(child: Text("Error:${snapshot.error}"));
} else {
var list = snapshot.data as List;
return ListView(
children: list.map((value) {
return Column(
children: [
ListTile(
title: Text("${value["title"]}"),
),
const Divider()
],
);
}).toList(),
);
}
} else {
return const Center(child: CircularProgressIndicator());
}
}),
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class NewsPage extends StatefulWidget {
const NewsPage({super.key});
State<NewsPage> createState() => _NewsPageState();
}
class _NewsPageState extends State<NewsPage> {
final ScrollController _scrollController = ScrollController();
final List _list = []; //数据
int _page = 1; //分页
bool _flag = true; //解决重复请求的问题
bool _hasData = true;
void initState() {
// TODO: implement initState
super.initState();
_getData();
//监听滚动条的事件
_scrollController.addListener(() {
// _scrollController.position.pixels //获取滚动条下拉的高度
// _scrollController.position.maxScrollExtent //获取页面的高度
if (_scrollController.position.pixels >
_scrollController.position.maxScrollExtent - 30) {
print("加载更多");
_getData();
}
});
}
_getData() async {
if (_flag && _hasData) {
_flag = false;
String apiUri =
"https://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=$_page";
print(apiUri);
var response = await Dio().get(apiUri);
// print(response.data is String); //false
var res = json.decode(response.data)["result"];
// print(newsData as Map); // true
setState(() {
_list.addAll(res);
_page++;
_flag = true;
});
//判断有没有数据
if (res.length < 20) {
setState(() {
_hasData = false;
});
}
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('下拉上拉加载'),
),
body: _list.isNotEmpty
? RefreshIndicator(
child: ListView.builder(
controller: _scrollController,
itemCount: _list.length,
itemBuilder: (context, index) {
if (index == _list.length - 1) {
return Column(
children: [
ListTile(
title:
Text("${_list[index]["title"]}", maxLines: 1),
),
const Divider(),
_progressIndicator()
],
);
} else {
return Column(
children: [
ListTile(
title:
Text("${_list[index]["title"]}", maxLines: 1),
),
const Divider()
],
);
}
}),
onRefresh: () async {
print("下拉刷新");
_getData();
})
: _progressIndicator(),
);
}
//自定义组件
Widget _progressIndicator() {
if (_hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return const Text("---我是有底线的---");
}
}
}
flutter_html
- flutter_html: 解析 html
import 'package:flutter/material.dart';
import './routers/routers.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: const AppBarTheme(
centerTitle: true,
)
),
initialRoute: "/",
onGenerateRoute: onGenerateRoute,
);
}
}
import 'package:flutter/cupertino.dart';
import '../pages/tabs.dart';
import '../pages/news.dart';
import '../pages/newsContent.dart';
//1、配置路由
Map routes = {
"/": (contxt) => const Tabs(),
"/news": (contxt) => const NewsPage(),
"/newsContent": (contxt,{arguments}) => NewsContentPage(arguments:arguments),
};
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // /news 或者 /search
final Function? pageContentBuilder =
routes[name]; // Function = (contxt) { return const NewsPage()}
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
import 'package:flutter/material.dart';
import './tabs/home.dart';
import './tabs/category.dart';
import './tabs/message.dart';
import './tabs/setting.dart';
import './tabs/user.dart';
class Tabs extends StatefulWidget {
final int index;
const Tabs({super.key,this.index=0});
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
late int _currentIndex;
void initState() {
// TODO: implement initState
super.initState();
_currentIndex=widget.index;
}
final List<Widget> _pages = const [
HomePage(),
CategoryPage(),
MessagePage(),
SettingPage(),
UserPage()
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
drawer: Drawer(
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: UserAccountsDrawerHeader(
accountName: const Text("itying"),
accountEmail: const Text("itying@qq.com"),
otherAccountsPictures:[
Image.network("https://www.itying.com/images/flutter/1.png"),
Image.network("https://www.itying.com/images/flutter/2.png"),
Image.network("https://www.itying.com/images/flutter/3.png"),
],
currentAccountPicture:const CircleAvatar(
backgroundImage:NetworkImage("https://www.itying.com/images/flutter/3.png")
),
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://www.itying.com/images/flutter/2.png"))),
))
],
),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.people),
),
title: Text("个人中心"),
),
const Divider(),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.settings),
),
title: Text("系统设置"),
),
const Divider(),
],
),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red, //选中的颜色
// iconSize:35, //底部菜单大小
currentIndex: _currentIndex, //第几个菜单选中
type: BottomNavigationBarType.fixed, //如果底部有4个或者4个以上的菜单的时候就需要配置这个参数
onTap: (index) {
//点击菜单触发的方法
//注意
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),
BottomNavigationBarItem(icon: Icon(Icons.message), label: "消息"),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),
BottomNavigationBarItem(icon: Icon(Icons.people), label: "用户")
]),
floatingActionButton: Container(
height: 60, //调整FloatingActionButton的大小
width: 60,
padding: const EdgeInsets.all(5),
margin: const EdgeInsets.only(top: 5), //调整FloatingActionButton的位置
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30),
),
child: FloatingActionButton(
backgroundColor: _currentIndex == 2 ? Colors.red : Colors.blue,
child: const Icon(Icons.add),
onPressed: () {
setState(() {
_currentIndex = 2;
});
}),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked, //配置浮动按钮的位置
);
}
}
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/news");
},
child: const Text("新闻页面 下拉加载 上拉分页")),
],
),
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class NewsPage extends StatefulWidget {
const NewsPage({super.key});
State<NewsPage> createState() => _NewsPageState();
}
class _NewsPageState extends State<NewsPage> {
final ScrollController _scrollController = ScrollController();
final List _list = []; //数据
int _page = 1; //分页
bool _flag = true; //解决重复请求的问题
bool _hasData = true;
void initState() {
// TODO: implement initState
super.initState();
_getData();
//监听滚动条的事件
_scrollController.addListener(() {
// _scrollController.position.pixels //获取滚动条下拉的高度
// _scrollController.position.maxScrollExtent //获取页面的高度
if (_scrollController.position.pixels >
_scrollController.position.maxScrollExtent - 30) {
print("加载更多");
_getData();
}
});
}
_getData() async {
if (_flag && _hasData) {
_flag = false;
String apiUri =
"https://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=$_page";
print(apiUri);
var response = await Dio().get(apiUri);
// print(response.data is String); //false
var res = json.decode(response.data)["result"];
// print(newsData as Map); // true
setState(() {
_list.addAll(res);
_page++;
_flag = true;
});
//判断有没有数据
if (res.length < 20) {
setState(() {
_hasData = false;
});
}
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('下拉上拉加载'),
),
body: _list.isNotEmpty
? RefreshIndicator(
child: ListView.builder(
controller: _scrollController,
itemCount: _list.length,
itemBuilder: (context, index) {
if (index == _list.length - 1) {
return Column(
children: [
ListTile(
title:
Text("${_list[index]["title"]}", maxLines: 1),
onTap: () {
Navigator.pushNamed(context, "/newsContent",
arguments: {"aid": _list[index]["aid"]});
},
),
const Divider(),
_progressIndicator()
],
);
} else {
return Column(
children: [
ListTile(
title:
Text("${_list[index]["title"]}", maxLines: 1),
onTap: () {
Navigator.pushNamed(context, "/newsContent",
arguments: {"aid": _list[index]["aid"]});
},
),
const Divider()
],
);
}
}),
onRefresh: () async {
print("下拉刷新");
_getData();
},
)
: _progressIndicator(),
);
}
//自定义组件
Widget _progressIndicator() {
if (_hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return const Text("---我是有底线的---");
}
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:flutter_html/flutter_html.dart';
class NewsContentPage extends StatefulWidget {
final Map arguments;
const NewsContentPage({super.key, required this.arguments});
State<NewsContentPage> createState() => _NewsContentPageState();
}
class _NewsContentPageState extends State<NewsContentPage> {
List _list = [];
void initState() {
// TODO: implement initState
super.initState();
print(widget.arguments["aid"]);
_getData();
}
_getData() async {
String apiUri =
"https://www.phonegap100.com/appapi.php?a=getPortalArticle&aid=${widget.arguments["aid"]}";
var response = await Dio().get(apiUri);
var res = json.decode(response.data);
print(res);
setState(() {
_list = json.decode(response.data)["result"];
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: _list.isNotEmpty
? ListView(
children: [
Text("${_list[0]["title"]}",
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 26)),
Padding(
padding: const EdgeInsets.all(10),
child: Html(
data: _list[0]["content"],
style: {
"body": Style(backgroundColor: Colors.white),
"p": Style(fontSize: FontSize.large),
},
onImageTap: ((url, context, attributes, element) {
print(url);
}),
onLinkTap: (url, context, attributes, element) {
print(url);
// webView
}),
),
],
)
: const Center(
child: CircularProgressIndicator(),
),
);
}
}
flutter_inappwebview
- flutter_inappwebview: 用于加载网页
// newsContent.dart
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
class NewsContentPage extends StatefulWidget {
final Map arguments;
const NewsContentPage({super.key, required this.arguments});
State<NewsContentPage> createState() => _NewsContentPageState();
}
class _NewsContentPageState extends State<NewsContentPage> {
bool _hasLoading = false;
void initState() {
// TODO: implement initState
super.initState();
print(widget.arguments["aid"]);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Column(
children: [
!_hasLoading ? const LinearProgressIndicator() : const Text(""),
Expanded(
child: InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse(
"https://www.phonegap100.com/newscontent.php?aid=${widget.arguments["aid"]}")),
onProgressChanged: (controller, progress) {
print(progress / 100);
if (progress / 100 > 0.999) {
setState(() {
_hasLoading = true;
});
}
},
),
)
],
),
);
}
}
device_info_plus connectivity_plus url_launcher
- url_launcher: 用于打开外部链接
- device_info_plus: 用于获取设备信息
- connectivity_plus: 用于获取网络状态
import 'package:flutter/material.dart';
import './routers/routers.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: "/",
onGenerateRoute: onGenerateRoute,
);
}
}
import 'package:flutter/cupertino.dart';
import '../pages/tabs.dart';
import '../pages/device.dart';
import '../pages/network.dart';
import '../pages/urlLauncher.dart';
//1、配置路由
Map routes = {
"/": (contxt) => const Tabs(),
"/device": (contxt) => const DevicePage(),
"/network": (contxt) => const NetworkPage(),
"/urlLauncher": (contxt) => const UrlLauncherPage(),
};
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // /news 或者 /search
final Function? pageContentBuilder =
routes[name]; // Function = (contxt) { return const NewsPage()}
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
import 'package:flutter/material.dart';
import './tabs/home.dart';
import './tabs/category.dart';
import './tabs/message.dart';
import './tabs/setting.dart';
import './tabs/user.dart';
class Tabs extends StatefulWidget {
const Tabs({super.key});
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int _currentIndex = 0;
final List<Widget> _pages = const [
HomePage(),
CategoryPage(),
MessagePage(),
SettingPage(),
UserPage()
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
drawer: Drawer(
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: UserAccountsDrawerHeader(
accountName: const Text("itying"),
accountEmail: const Text("itying@qq.com"),
otherAccountsPictures: [
Image.network(
"https://www.itying.com/images/flutter/1.png"),
Image.network(
"https://www.itying.com/images/flutter/2.png"),
Image.network(
"https://www.itying.com/images/flutter/3.png"),
],
currentAccountPicture: const CircleAvatar(
backgroundImage: NetworkImage(
"https://www.itying.com/images/flutter/3.png")),
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://www.itying.com/images/flutter/2.png"))),
),
)
],
),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.people),
),
title: Text("个人中心"),
),
const Divider(),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.settings),
),
title: Text("系统设置"),
),
const Divider(),
],
),
),
endDrawer: const Drawer(
child: Text("右侧侧边栏"),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red, //选中的颜色
// iconSize:35, //底部菜单大小
currentIndex: _currentIndex, //第几个菜单选中
type: BottomNavigationBarType.fixed, //如果底部有4个或者4个以上的菜单的时候就需要配置这个参数
onTap: (index) {
//点击菜单触发的方法
//注意
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),
BottomNavigationBarItem(icon: Icon(Icons.message), label: "消息"),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),
BottomNavigationBarItem(icon: Icon(Icons.people), label: "用户")
]),
floatingActionButton: Container(
height: 60, //调整FloatingActionButton的大小
width: 60,
padding: const EdgeInsets.all(5),
margin: const EdgeInsets.only(top: 5), //调整FloatingActionButton的位置
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30),
),
child: FloatingActionButton(
backgroundColor: _currentIndex == 2 ? Colors.red : Colors.blue,
child: const Icon(Icons.add),
onPressed: () {
setState(() {
_currentIndex = 2;
});
}),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked, //配置浮动按钮的位置
);
}
}
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/device");
},
child: const Text("Device设备插件")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/network");
},
child: const Text("检测网络变化")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/urlLauncher");
},
child: const Text("urlLauncher")),
const SizedBox(
height: 20,
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:device_info_plus/device_info_plus.dart';
class DevicePage extends StatefulWidget {
const DevicePage({super.key});
State<DevicePage> createState() => _DevicePageState();
}
class _DevicePageState extends State<DevicePage> {
List<Widget> _list = [];
void initState() {
super.initState();
_getDeviceInfo();
}
_getDeviceInfo() async {
final deviceInfoPlugin = DeviceInfoPlugin();
final deviceInfo = await deviceInfoPlugin.deviceInfo;
final deviceInfoMap = deviceInfo.toMap();
print(deviceInfo);
var tempList = deviceInfoMap.entries.map((e) {
return ListTile(
title: Text("${e.key}:${e.value}"),
);
}).toList();
setState(() {
_list = tempList;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Device演示'),
),
body: ListView(
children: _list,
),
);
}
}
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
class NetworkPage extends StatefulWidget {
const NetworkPage({super.key});
State<NetworkPage> createState() => _NetworkPageState();
}
class _NetworkPageState extends State<NetworkPage> {
late StreamSubscription<ConnectivityResult> subscription;
void initState() {
// TODO: implement initState
super.initState();
subscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) {
// Got a new connectivity status!
print(result);
if (result == ConnectivityResult.wifi) {
print("wifi");
} else if (result == ConnectivityResult.mobile) {
print("手机网络");
} else if (result == ConnectivityResult.ethernet) {
print("ethernet");
} else {
print("没有网络");
}
});
}
void dispose() {
// TODO: implement dispose
super.dispose();
subscription.cancel(); //关闭监听
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('检测网络'),
),
body: const Center(
child: Text("检测网络"),
),
);
}
}
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class UrlLauncherPage extends StatefulWidget {
const UrlLauncherPage({super.key});
State<UrlLauncherPage> createState() => _UrlLauncherPageState();
}
class _UrlLauncherPageState extends State<UrlLauncherPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('UrlLauncherPage'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
Uri url = Uri.parse('https://www.itying.com');
if (await canLaunchUrl(url)) {
await launchUrl(url);
} else {
print("没法打开这个地址");
}
},
child: const Text("打开浏览器")),
const SizedBox(height: 10),
ElevatedButton(
child: const Text('拨打电话'),
onPressed: () async {
final Uri tel = Uri.parse('tel:10086');
if (await canLaunchUrl(tel)) {
await launchUrl(tel);
} else {
throw 'Could not launch $tel';
}
},
),
const SizedBox(height: 10),
ElevatedButton(
child: const Text('发送短信'),
onPressed: () async {
final Uri tel = Uri.parse('sms:10086');
if (await canLaunchUrl(tel)) {
await launchUrl(tel);
} else {
throw 'Could not launch $tel';
}
},
),
const SizedBox(height: 10),
ElevatedButton(
child: const Text('打开支付宝'),
onPressed: () async {
final Uri tel = Uri.parse('alipays://');
if (await canLaunchUrl(tel)) {
await launchUrl(tel);
} else {
throw 'Could not launch $tel';
}
},
),
const SizedBox(height: 10),
ElevatedButton(
child: const Text('打开外部应用-高德地图'),
onPressed: () async {
//https://lbs.amap.com/tools/picker
String title = "北京大学";
String latitude = "39.992806"; //纬度
String longitude = "116.310905"; // 经度
Uri uri = Uri.parse(
'${Platform.isAndroid ? 'android' : 'ios'}amap://navi?sourceApplication=amap&lat=$latitude&lon=$longitude&dev=0&style=2&poiname=$title');
try {
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
} else {
print('无法调起高德地图');
}
} catch (e) {
print('无法调起高德地图');
}
},
),
],
),
),
);
}
}
video_player chewie
- video_player: 视频播放
- chewie: 视频播放器
import 'package:flutter/cupertino.dart';
import '../pages/tabs.dart';
import '../pages/device.dart';
import '../pages/network.dart';
import '../pages/urlLauncher.dart';
import '../pages/video.dart';
import '../pages/chewieVideo.dart';
//1、配置路由
Map routes = {
"/": (contxt) => const Tabs(),
"/device": (contxt) => const DevicePage(),
"/network": (contxt) => const NetworkPage(),
"/urlLauncher": (contxt) => const UrlLauncherPage(),
"/video": (contxt) => const VideoPage(),
"/chewieVideo": (contxt) => const ChewieVideoPage(),
};
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // /news 或者 /search
final Function? pageContentBuilder =
routes[name]; // Function = (contxt) { return const NewsPage()}
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/device");
},
child: const Text("Device设备插件")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/network");
},
child: const Text("检测网络变化")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/urlLauncher");
},
child: const Text("urlLauncher")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/video");
},
child: const Text("video播放视频")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/chewieVideo");
},
child: const Text("chewie播放视频")),
const SizedBox(
height: 20,
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoPage extends StatefulWidget {
const VideoPage({super.key});
State<VideoPage> createState() => _VideoPageState();
}
class _VideoPageState extends State<VideoPage> {
late VideoPlayerController _controller;
void initState() {
super.initState();
_controller = VideoPlayerController.network(
'https://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4')
..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
print("initialized");
});
}
void dispose() {
// TODO: implement dispose
super.dispose();
_controller.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("video VideoPlayer"),
),
body: Center(
child: _controller.value.isInitialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: Container(color: Colors.red),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
});
},
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:chewie/chewie.dart';
import 'package:video_player/video_player.dart';
class ChewieVideoPage extends StatefulWidget {
const ChewieVideoPage({super.key});
State<ChewieVideoPage> createState() => _ChewieVideoPageState();
}
class _ChewieVideoPageState extends State<ChewieVideoPage> {
late ChewieController chewieController;
late VideoPlayerController videoPlayerController;
void initState() {
// TODO: implement initState
super.initState();
videoPlayerController = VideoPlayerController.network(
'https://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4');
chewieController = ChewieController(
videoPlayerController: videoPlayerController,
aspectRatio: 3 / 2, //配置视频的宽高比
autoPlay: true,
// looping: true,
optionsBuilder: (context, defaultOptions) async {
await showModalBottomSheet(
context: context,
builder: (context) {
return SizedBox(
height: 200,
child: ListView(
children: [
ListTile(
title: const Text("播放速度"),
onTap: () {
defaultOptions[0].onTap!();
},
),
ListTile(
title: const Text("取消"),
onTap: () {
Navigator.pop(context);
},
)
],
),
);
},
);
},
);
}
//返回的时候需要销毁
void dispose() {
videoPlayerController.dispose();
chewieController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('在线视频播放'),
),
body: Center(
child: AspectRatio(
aspectRatio: 3 / 2,
child: Chewie(
controller: chewieController,
),
),
),
);
}
}
image_picker
- image_picker: 用于从图像库中选择图像或拍摄新照片的 Flutter 插件。
import 'package:flutter/cupertino.dart';
import '../pages/tabs.dart';
import '../pages/device.dart';
import '../pages/network.dart';
import '../pages/urlLauncher.dart';
import '../pages/video.dart';
import '../pages/chewieVideo.dart';
import '../pages/imagePicker.dart';
import '../pages/videoPicker.dart';
//1、配置路由
Map routes = {
"/": (contxt) => const Tabs(),
"/device": (contxt) => const DevicePage(),
"/network": (contxt) => const NetworkPage(),
"/urlLauncher": (contxt) => const UrlLauncherPage(),
"/video": (contxt) => const VideoPage(),
"/chewieVideo": (contxt) => const ChewieVideoPage(),
"/imagePicker": (contxt) => const ImagePickerPage(),
"/videoPicker": (contxt) => const VideoPickerPage(),
};
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // /news 或者 /search
final Function? pageContentBuilder =
routes[name]; // Function = (contxt) { return const NewsPage()}
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/device");
},
child: const Text("Device设备插件")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/network");
},
child: const Text("检测网络变化")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/urlLauncher");
},
child: const Text("urlLauncher")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/video");
},
child: const Text("video播放视频")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/chewieVideo");
},
child: const Text("chewie播放视频")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/imagePicker");
},
child: const Text("拍照 相册选择图片")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/videoPicker");
},
child: const Text("录制视频 相册选择视频")),
const SizedBox(
height: 20,
),
],
),
);
}
}
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class ImagePickerPage extends StatefulWidget {
const ImagePickerPage({super.key});
State<ImagePickerPage> createState() => _ImagePickerPageState();
}
class _ImagePickerPageState extends State<ImagePickerPage> {
final ImagePicker _picker = ImagePicker();
XFile? _pickedFile;
//拍照
_pickerCamera() async {
XFile? pickedFile = await _picker.pickImage(
source: ImageSource.camera, maxWidth: 800, maxHeight: 800);
if (pickedFile != null) {
// print(pickedFile.path);
setState(() {
_pickedFile = pickedFile;
});
}
}
//相册选择
_pickerGallery() async {
XFile? pickedFile = await _picker.pickImage(
source: ImageSource.gallery, maxWidth: 800, maxHeight: 800);
if (pickedFile != null) {
setState(() {
_pickedFile = pickedFile;
});
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Center(
child: ListView(
padding: const EdgeInsets.all(20),
children: [
ElevatedButton(onPressed: _pickerCamera, child: const Text("拍照")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: _pickerGallery, child: const Text("相册选择")),
const SizedBox(height: 20),
_pickedFile == null
? const Text("选择照片...")
: Image.file(File(_pickedFile!.path)), //引入dart:io库
],
),
),
);
}
}
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:chewie/chewie.dart';
import 'package:video_player/video_player.dart';
class VideoPickerPage extends StatefulWidget {
const VideoPickerPage({super.key});
State<VideoPickerPage> createState() => _VideoPickerPageState();
}
class _VideoPickerPageState extends State<VideoPickerPage> {
final ImagePicker _picker = ImagePicker();
XFile? _pickedFile;
//配置加载视频
late ChewieController chewieController;
late VideoPlayerController videoPlayerController;
void initState() {
super.initState();
}
_initVideo(fileDir) async {
videoPlayerController = VideoPlayerController.file(fileDir);
//初始化完成后才可以获取宽高比
await videoPlayerController.initialize();
chewieController = ChewieController(
videoPlayerController: videoPlayerController,
aspectRatio: videoPlayerController.value.aspectRatio, //配置视频的宽高比
autoPlay: true,
);
}
void dispose() {
super.dispose();
try {
videoPlayerController.dispose();
chewieController.dispose();
} catch (e) {
print(e);
}
}
//录制视频
_pickerCameraVideo() async {
XFile? pickedFile = await _picker.pickVideo(source: ImageSource.camera);
if (pickedFile != null) {
// print(pickedFile.path);
// print(File(pickedFile.path));
await _initVideo(File(pickedFile.path));
setState(() {
_pickedFile = pickedFile;
});
}
}
//相册选择视频
_pickerGalleryVideo() async {
XFile? pickedFile = await _picker.pickVideo(source: ImageSource.gallery);
if (pickedFile != null) {
await _initVideo(File(pickedFile.path));
setState(() {
_pickedFile = pickedFile;
});
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Center(
child: ListView(
padding: const EdgeInsets.all(20),
children: [
ElevatedButton(
onPressed: _pickerCameraVideo, child: const Text("录制视频")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: _pickerGalleryVideo, child: const Text("相册选择视频")),
const SizedBox(height: 20),
_pickedFile == null
? const Text("选择视频")
: AspectRatio(
aspectRatio: videoPlayerController.value.aspectRatio,
child: Chewie(controller: chewieController),
)
],
),
),
);
}
}
dio 与 ImagePicker 上传图片
- dio
- 注意: 要修改
Info.plist
文件:NSPhotoLibraryUsageDescription
、NSCameraUsageDescription
、NSMicrophoneUsageDescription
。
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:chewie/chewie.dart';
import 'package:video_player/video_player.dart';
import 'package:dio/dio.dart';
class VideoPickerPage extends StatefulWidget {
const VideoPickerPage({super.key});
State<VideoPickerPage> createState() => _VideoPickerPageState();
}
class _VideoPickerPageState extends State<VideoPickerPage> {
final ImagePicker _picker = ImagePicker();
XFile? _pickedFile;
//配置加载视频
late ChewieController chewieController;
late VideoPlayerController videoPlayerController;
void initState() {
super.initState();
}
_initVideo(fileDir) async {
videoPlayerController = VideoPlayerController.file(fileDir);
//初始化完成后才可以获取宽高比
await videoPlayerController.initialize();
chewieController = ChewieController(
videoPlayerController: videoPlayerController,
aspectRatio: videoPlayerController.value.aspectRatio, //配置视频的宽高比
autoPlay: true,
);
}
void dispose() {
super.dispose();
try {
videoPlayerController.dispose();
chewieController.dispose();
} catch (e) {
print(e);
}
}
//录制视频
_pickerCameraVideo() async {
XFile? pickedFile = await _picker.pickVideo(source: ImageSource.camera);
if (pickedFile != null) {
// print(pickedFile.path);
// print(File(pickedFile.path));
//加载视频
await _initVideo(File(pickedFile.path));
//上传视频
_uplodFile(pickedFile.path);
setState(() {
_pickedFile = pickedFile;
});
}
}
//相册选择视频
_pickerGalleryVideo() async {
XFile? pickedFile = await _picker.pickVideo(source: ImageSource.gallery);
if (pickedFile != null) {
//加载视频
await _initVideo(File(pickedFile.path));
//上传视频
_uplodFile(pickedFile.path);
setState(() {
_pickedFile = pickedFile;
});
}
}
//上传视频 需要压缩视频
_uplodFile(videoDir) async{
var formData = FormData.fromMap({
'username': 'itying.com',
'age': 25,
'file': await MultipartFile.fromFile(videoDir,filename: 'xxxx.mp4')
});
//https://jd.itying.com/public/upload/orXDAXMHW9XsAxMKYZix-Lpu.mp4
var response = await Dio().post('https://jd.itying.com/imgupload', data: formData);
print(response.data);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Center(
child: ListView(
padding: const EdgeInsets.all(20),
children: [
ElevatedButton(
onPressed: _pickerCameraVideo, child: const Text("录制视频")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: _pickerGalleryVideo, child: const Text("相册选择视频")),
const SizedBox(height: 20),
_pickedFile == null
? const Text("选择视频")
: AspectRatio(
aspectRatio: videoPlayerController.value.aspectRatio,
child: Chewie(controller: chewieController),
)
],
),
),
);
}
}
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:dio/dio.dart';
class ImagePickerPage extends StatefulWidget {
const ImagePickerPage({super.key});
State<ImagePickerPage> createState() => _ImagePickerPageState();
}
class _ImagePickerPageState extends State<ImagePickerPage> {
final ImagePicker _picker = ImagePicker();
XFile? _pickedFile;
//拍照
_pickerCamera() async {
XFile? pickedFile = await _picker.pickImage(
source: ImageSource.camera, maxWidth: 800, maxHeight: 800);
if (pickedFile != null) {
// print(pickedFile.path);
//上传图片
_uplodFile(pickedFile.path);
setState(() {
_pickedFile = pickedFile;
});
}
}
//相册选择
_pickerGallery() async {
XFile? pickedFile = await _picker.pickImage(
source: ImageSource.gallery, maxWidth: 800, maxHeight: 800);
if (pickedFile != null) {
//上传图片
_uplodFile(pickedFile.path);
setState(() {
_pickedFile = pickedFile;
});
}
}
//上传图片
_uplodFile(imageDir) async {
var formData = FormData.fromMap({
'username': 'itying.com',
'age': 25,
'file': await MultipartFile.fromFile(imageDir, filename: 'xxxx.jpg')
});
// https://jd.itying.com/public/upload/ill8K_ZrJWb3OZWrco_LmslO.jpg
var response =
await Dio().post('https://jd.itying.com/imgupload', data: formData);
print(response.data);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Center(
child: ListView(
padding: const EdgeInsets.all(20),
children: [
ElevatedButton(onPressed: _pickerCamera, child: const Text("拍照")),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: _pickerGallery, child: const Text("相册选择")),
const SizedBox(height: 20),
_pickedFile == null
? const Text("选择照片...")
: Image.file(File(_pickedFile!.path)), //引入dart:io库
],
),
),
);
}
}
shared_preferences
- shared_preferences: 用于存储轻量级的键值对数据。
import 'package:flutter/material.dart';
import './routers/routers.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: "/",
onGenerateRoute: onGenerateRoute,
);
}
}
import 'package:flutter/cupertino.dart';
import '../pages/tabs.dart';
import '../pages/storage.dart';
//1、配置路由
Map routes = {
"/": (contxt) => const Tabs(),
"/storage": (contxt) => const StoragePage(),
};
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // /news 或者 /search
final Function? pageContentBuilder =
routes[name]; // Function = (contxt) { return const NewsPage()}
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
import 'package:flutter/material.dart';
import './tabs/home.dart';
import './tabs/category.dart';
import './tabs/message.dart';
import './tabs/setting.dart';
import './tabs/user.dart';
class Tabs extends StatefulWidget {
const Tabs({super.key});
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int _currentIndex = 0;
final List<Widget> _pages = const [
HomePage(),
CategoryPage(),
MessagePage(),
SettingPage(),
UserPage()
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
drawer: Drawer(
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: UserAccountsDrawerHeader(
accountName: const Text("itying"),
accountEmail: const Text("itying@qq.com"),
otherAccountsPictures: [
Image.network(
"https://www.itying.com/images/flutter/1.png"),
Image.network(
"https://www.itying.com/images/flutter/2.png"),
Image.network(
"https://www.itying.com/images/flutter/3.png"),
],
currentAccountPicture: const CircleAvatar(
backgroundImage: NetworkImage(
"https://www.itying.com/images/flutter/3.png")),
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://www.itying.com/images/flutter/2.png"))),
))
],
),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.people),
),
title: Text("个人中心"),
),
const Divider(),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.settings),
),
title: Text("系统设置"),
),
const Divider(),
],
),
),
endDrawer: const Drawer(
child: Text("右侧侧边栏"),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red, //选中的颜色
// iconSize:35, //底部菜单大小
currentIndex: _currentIndex, //第几个菜单选中
type: BottomNavigationBarType.fixed, //如果底部有4个或者4个以上的菜单的时候就需要配置这个参数
onTap: (index) {
//点击菜单触发的方法
//注意
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),
BottomNavigationBarItem(icon: Icon(Icons.message), label: "消息"),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),
BottomNavigationBarItem(icon: Icon(Icons.people), label: "用户")
]),
floatingActionButton: Container(
height: 60, //调整FloatingActionButton的大小
width: 60,
padding: const EdgeInsets.all(5),
margin: const EdgeInsets.only(top: 5), //调整FloatingActionButton的位置
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30),
),
child: FloatingActionButton(
backgroundColor: _currentIndex == 2 ? Colors.red : Colors.blue,
child: const Icon(Icons.add),
onPressed: () {
setState(() {
_currentIndex = 2;
});
}),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked, //配置浮动按钮的位置
);
}
}
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/storage");
},
child: const Text("storage本地存储")),
const SizedBox(
height: 20,
)
],
),
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class StoragePage extends StatefulWidget {
const StoragePage({super.key});
State<StoragePage> createState() => _StoragePageState();
}
class _StoragePageState extends State<StoragePage> {
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
_saveData() async {
final prefs = await _prefs;
prefs.setString("username", "张三");
prefs.setInt("age", 20);
List<String> userinfo = ["张三", "李四", "王五"];
prefs.setStringList("userinfo", userinfo);
List<Map> newsList = [
{"title": "我是一个标题"},
{"title": "我是二个标题"},
{"title": "我是一个标题"},
{"title": "我是一个标题"},
{"title": "我是一个标题"},
];
prefs.setString("newsList", json.encode(newsList));
}
_getData() async {
final prefs = await _prefs;
String? username = prefs.getString("username");
print(username);
int? age = prefs.getInt("age");
print(age);
List<String>? list = prefs.getStringList("userinfo");
print(list);
print(list![0]);
//获取List<Map>
String? newsList = prefs.getString("newsList");
var tempData = json.decode(newsList!);
print(tempData[0]);
print(tempData[0]["title"]);
}
_removeData() async {
final prefs = await _prefs;
prefs.remove("username");
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _saveData,
child: const Text('保存数据'),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: _getData,
child: const Text('获取数据'),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: _removeData,
child: const Text('清除数据'),
)
],
),
),
);
}
}
// 封装本地存储
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class Storage {
static setData(String key, dynamic value) async {
var prefs = await SharedPreferences.getInstance();
prefs.setString(key, json.encode(value));
}
static getData(String key) async {
var prefs = await SharedPreferences.getInstance();
String? tempData = prefs.getString(key);
return json.decode(tempData!);
}
static removeData(String key) async {
var prefs = await SharedPreferences.getInstance();
prefs.remove(key);
}
}
barcode_scan2
- barcode_scan2: 二维码扫描
import 'package:flutter/material.dart';
import './routers/routers.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: "/",
onGenerateRoute: onGenerateRoute,
);
}
}
import 'package:flutter/cupertino.dart';
import '../pages/tabs.dart';
import '../pages/barcodeScan.dart';
//1、配置路由
Map routes = {
"/": (contxt) => const Tabs(),
"/barcodeScan": (contxt) => const BarcodeScanPage(),
};
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // /news 或者 /search
final Function? pageContentBuilder =
routes[name]; // Function = (contxt) { return const NewsPage()}
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
import 'package:flutter/material.dart';
import './tabs/home.dart';
import './tabs/category.dart';
import './tabs/message.dart';
import './tabs/setting.dart';
import './tabs/user.dart';
class Tabs extends StatefulWidget {
const Tabs({super.key});
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int _currentIndex = 0;
final List<Widget> _pages = const [
HomePage(),
CategoryPage(),
MessagePage(),
SettingPage(),
UserPage()
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
drawer: Drawer(
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: UserAccountsDrawerHeader(
accountName: const Text("itying"),
accountEmail: const Text("itying@qq.com"),
otherAccountsPictures: [
Image.network(
"https://www.itying.com/images/flutter/1.png"),
Image.network(
"https://www.itying.com/images/flutter/2.png"),
Image.network(
"https://www.itying.com/images/flutter/3.png"),
],
currentAccountPicture: const CircleAvatar(
backgroundImage: NetworkImage(
"https://www.itying.com/images/flutter/3.png")),
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://www.itying.com/images/flutter/2.png"))),
))
],
),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.people),
),
title: Text("个人中心"),
),
const Divider(),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.settings),
),
title: Text("系统设置"),
),
const Divider(),
],
),
),
endDrawer: const Drawer(
child: Text("右侧侧边栏"),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red, //选中的颜色
// iconSize:35, //底部菜单大小
currentIndex: _currentIndex, //第几个菜单选中
type: BottomNavigationBarType.fixed, //如果底部有4个或者4个以上的菜单的时候就需要配置这个参数
onTap: (index) {
//点击菜单触发的方法
//注意
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),
BottomNavigationBarItem(icon: Icon(Icons.message), label: "消息"),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),
BottomNavigationBarItem(icon: Icon(Icons.people), label: "用户")
]),
floatingActionButton: Container(
height: 60, //调整FloatingActionButton的大小
width: 60,
padding: const EdgeInsets.all(5),
margin: const EdgeInsets.only(top: 5), //调整FloatingActionButton的位置
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30),
),
child: FloatingActionButton(
backgroundColor: _currentIndex == 2 ? Colors.red : Colors.blue,
child: const Icon(Icons.add),
onPressed: () {
setState(() {
_currentIndex = 2;
});
}),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked, //配置浮动按钮的位置
);
}
}
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/barcodeScan");
},
child: const Text("扫码")),
const SizedBox(
height: 20,
)
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:barcode_scan2/barcode_scan2.dart';
class BarcodeScanPage extends StatefulWidget {
const BarcodeScanPage({super.key});
State<BarcodeScanPage> createState() => _BarcodeScanPageState();
}
class _BarcodeScanPageState extends State<BarcodeScanPage> {
void _doBarcodeScan() async {
var options = const ScanOptions(
// set the options
autoEnableFlash: true,
strings: {
'cancel': '取消',
'flash_on': '打开Flash',
'flash_off': '关闭Flash',
});
var result = await BarcodeScanner.scan(options: options);
print(result.type); // The result type (barcode, cancelled, failed)
print(result.rawContent); // The barcode content
print(result.format); // The barcode format (as enum)
print(result
.formatNote); // If a unknown format was scanned this field contains a note
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("扫码演示")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _doBarcodeScan,
child: const Text("扫描二维码 条形码"),
)
],
),
),
);
}
}