
开篇寄语
这一篇文章主要是学习flutter中各种在App中可能出现的实用功能,比如白天模式与夜间模式自由切换,分享到社交媒体,照相摄像,打分五星好评之类的等等,一起来看看都有什么吧。
前情提要
- 《如何在Mac M1芯片电脑上安装Flutter并建立自己第一个全系统应用》
- 《如何在Windows电脑上安装Flutter并建立自己第一个全系统应用》
- 《Flutter制作自己的第一个全平台APP学习之Navigation篇》
- 《Flutter制作自己的第一个全平台APP学习之Popup篇》
- 《Flutter制作自己的第一个全平台APP学习之多媒体篇》
内容详情
以下内容大多是更改lib下的main.dart文件内容,删掉里面的内容,复制粘贴代码,开启调试就可以出现了。
白天与夜间模式切换
- 夜间模式现在在制作App中很流行,Flutter中也很容易实现,试举例如下:
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// Using "static" so that we can easily access it later
static final ValueNotifier<ThemeMode> themeNotifier =
ValueNotifier(ThemeMode.light);
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<ThemeMode>(
valueListenable: themeNotifier,
builder: (_, ThemeMode currentMode, __) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.amber),
darkTheme: ThemeData.dark(),
themeMode: currentMode,
home: HomeScreen(),
);
});
}
}
// Home Screen
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo'),
actions: [
IconButton(
icon: Icon(MyApp.themeNotifier.value == ThemeMode.light
? Icons.dark_mode
: Icons.light_mode),
onPressed: () {
MyApp.themeNotifier.value =
MyApp.themeNotifier.value == ThemeMode.light
? ThemeMode.dark
: ThemeMode.light;
})
],
),
body: Center(
child: ElevatedButton(
child: Text('Go to Other Screen'),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => OtherScreen()));
},
),
),
);
}
}
// Other Screen
class OtherScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Other Screen'),
),
body: Center(
child: Text(
'Hello',
style: TextStyle(fontSize: 50),
),
),
);
}
}
生成效果如下图所示:
文字添加超链接
- 就像是html中的<a></a>标签,点击后就会跳转到网页,试举例如下:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo'),
),
body: Padding(
padding: const EdgeInsets.all(30),
child: DefaultTextStyle(
style: TextStyle(fontSize: 24, color: Colors.black87),
child: Wrap(
children: [
Text('Welcome to '),
GestureDetector(
child: Text(
'Flutter Dev',
style: TextStyle(
color: Colors.blue, decoration: TextDecoration.underline),
),
onTap: () async => await canLaunch('https://www.flutter.dev')
? await launch('https://www.flutter.dev')
: throw 'Something bad happend',
),
],
),
),
),
);
}
}
生成效果如下图所示:
复制粘贴到剪切板
- 这个功能也是十分常见的,所以也需要掌握的,试举例如下:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
TextEditingController _textController = TextEditingController();
// This key will be used to show the snack bar
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
// This function is triggered when the copy icon is pressed
Future<void> _copyToClipboard() async {
await Clipboard.setData(ClipboardData(text: _textController.text));
_scaffoldKey.currentState!.showSnackBar(SnackBar(
content: Text('Copied to clipboard'),
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text('Flutter Demo'),
backgroundColor: Colors.deepOrange,
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(30),
child: TextField(
controller: _textController,
decoration: InputDecoration(
icon: IconButton(
icon: Icon(Icons.copy),
onPressed: _copyToClipboard,
),
),
),
)));
}
}
生成效果如下图所示:

分享按钮
- 各种消息分享到社交媒体的功能,岂能错过,除了有更多乐趣外,还能扩大App的知名度哦,试举一例:
- 需要添加一个名为share的支撑库,安装和使用方法请参看这个地址:share
import 'package:flutter/material.dart';
import 'package:share/share.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
final String _content =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum diam ipsum, lobortis quis ultricies non, lacinia at justo.';
void _shareContent() {
Share.share(_content);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo'),
),
body: Padding(
padding: const EdgeInsets.all(25),
child: Center(
child: Column(children: [
Text(_content),
SizedBox(height: 15),
ElevatedButton.icon(
onPressed: _shareContent,
icon: Icon(Icons.share),
label: Text('Share This Sentence'))
]),
),
),
);
}
}
生成效果如下图所示:

五星好评
- 这个常见于打分环节,自然也要掌握啦,试举一例:
- 需要安装一个名为flutter rating bar的支撑库,地址是这里:flutter_rating_bar,安装完成后,可以参考下面这个代码案例:
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final _ratingController;
late double _rating;
double _userRating = 3.0;
int _ratingBarMode = 1;
double _initialRating = 2.0;
bool _isRTLMode = false;
bool _isVertical = false;
IconData? _selectedIcon;
@override
void initState() {
super.initState();
_ratingController = TextEditingController(text: '3.0');
_rating = _initialRating;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.amber,
appBarTheme: AppBarTheme(
textTheme: TextTheme(
headline6: Theme.of(context)
.textTheme
.headline6
?.copyWith(color: Colors.white),
),
),
),
home: Builder(
builder: (context) => Scaffold(
appBar: AppBar(
title: Text('Flutter Rating Bar'),
actions: [
IconButton(
icon: Icon(Icons.settings),
color: Colors.white,
onPressed: () async {
_selectedIcon = await showDialog<IconData>(
context: context,
builder: (context) => IconAlert(),
);
_ratingBarMode = 1;
setState(() {});
},
),
],
),
body: Directionality(
textDirection: _isRTLMode ? TextDirection.rtl : TextDirection.ltr,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 40.0,
),
_heading('Rating Bar'),
_ratingBar(_ratingBarMode),
SizedBox(height: 20.0),
Text(
'Rating: $_rating',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 40.0),
_heading('Rating Indicator'),
RatingBarIndicator(
rating: _userRating,
itemBuilder: (context, index) => Icon(
_selectedIcon ?? Icons.star,
color: Colors.amber,
),
itemCount: 5,
itemSize: 50.0,
unratedColor: Colors.amber.withAlpha(50),
direction: _isVertical ? Axis.vertical : Axis.horizontal,
),
SizedBox(height: 20.0),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: TextFormField(
controller: _ratingController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter rating',
labelText: 'Enter rating',
suffixIcon: MaterialButton(
onPressed: () {
_userRating =
double.parse(_ratingController.text ?? '0.0');
setState(() {});
},
child: Text('Rate'),
),
),
),
),
SizedBox(height: 40.0),
_heading('Scrollable Rating Indicator'),
RatingBarIndicator(
rating: 8.2,
itemCount: 20,
itemSize: 30.0,
physics: BouncingScrollPhysics(),
itemBuilder: (context, _) => Icon(
Icons.star,
color: Colors.amber,
),
),
SizedBox(height: 20.0),
Text(
'Rating Bar Modes',
style: TextStyle(fontWeight: FontWeight.w300),
),
Row(
children: [
_radio(1),
_radio(2),
_radio(3),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Switch to Vertical Bar',
style: TextStyle(fontWeight: FontWeight.w300),
),
Switch(
value: _isVertical,
onChanged: (value) {
setState(() {
_isVertical = value;
});
},
activeColor: Colors.amber,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Switch to RTL Mode',
style: TextStyle(fontWeight: FontWeight.w300),
),
Switch(
value: _isRTLMode,
onChanged: (value) {
setState(() {
_isRTLMode = value;
});
},
activeColor: Colors.amber,
),
],
),
],
),
),
),
),
),
);
}
Widget _radio(int value) {
return Expanded(
child: RadioListTile<int>(
value: value,
groupValue: _ratingBarMode,
dense: true,
title: Text(
'Mode $value',
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 12.0,
),
),
onChanged: (value) {
setState(() {
_ratingBarMode = value!;
});
},
),
);
}
Widget _ratingBar(int mode) {
switch (mode) {
case 1:
return RatingBar.builder(
initialRating: _initialRating,
minRating: 1,
direction: _isVertical ? Axis.vertical : Axis.horizontal,
allowHalfRating: true,
unratedColor: Colors.amber.withAlpha(50),
itemCount: 5,
itemSize: 50.0,
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
itemBuilder: (context, _) => Icon(
_selectedIcon ?? Icons.star,
color: Colors.amber,
),
onRatingUpdate: (rating) {
setState(() {
_rating = rating;
});
},
updateOnDrag: true,
);
case 2:
return RatingBar(
initialRating: _initialRating,
direction: _isVertical ? Axis.vertical : Axis.horizontal,
allowHalfRating: true,
itemCount: 5,
ratingWidget: RatingWidget(
full: _image('assets/heart.png'),
half: _image('assets/heart_half.png'),
empty: _image('assets/heart_border.png'),
),
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
onRatingUpdate: (rating) {
setState(() {
_rating = rating;
});
},
updateOnDrag: true,
);
case 3:
return RatingBar.builder(
initialRating: _initialRating,
direction: _isVertical ? Axis.vertical : Axis.horizontal,
itemCount: 5,
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
itemBuilder: (context, index) {
switch (index) {
case 0:
return Icon(
Icons.sentiment_very_dissatisfied,
color: Colors.red,
);
case 1:
return Icon(
Icons.sentiment_dissatisfied,
color: Colors.redAccent,
);
case 2:
return Icon(
Icons.sentiment_neutral,
color: Colors.amber,
);
case 3:
return Icon(
Icons.sentiment_satisfied,
color: Colors.lightGreen,
);
case 4:
return Icon(
Icons.sentiment_very_satisfied,
color: Colors.green,
);
default:
return Container();
}
},
onRatingUpdate: (rating) {
setState(() {
_rating = rating;
});
},
updateOnDrag: true,
);
default:
return Container();
}
}
Widget _image(String asset) {
return Image.asset(
asset,
height: 30.0,
width: 30.0,
color: Colors.amber,
);
}
Widget _heading(String text) => Column(
children: [
Text(
text,
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 24.0,
),
),
SizedBox(
height: 20.0,
),
],
);
}
class IconAlert extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(
'Select Icon',
style: TextStyle(
fontWeight: FontWeight.w300,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
titlePadding: EdgeInsets.all(12.0),
contentPadding: EdgeInsets.all(0),
content: Wrap(
children: [
_iconButton(context, Icons.home),
_iconButton(context, Icons.airplanemode_active),
_iconButton(context, Icons.euro_symbol),
_iconButton(context, Icons.beach_access),
_iconButton(context, Icons.attach_money),
_iconButton(context, Icons.music_note),
_iconButton(context, Icons.android),
_iconButton(context, Icons.toys),
_iconButton(context, Icons.language),
_iconButton(context, Icons.landscape),
_iconButton(context, Icons.ac_unit),
_iconButton(context, Icons.star),
],
),
);
}
Widget _iconButton(BuildContext context, IconData icon) => IconButton(
icon: Icon(icon),
onPressed: () => Navigator.pop(context, icon),
splashColor: Colors.amberAccent,
color: Colors.amber,
);
}
生成效果如下图所示:

右下角弹出按钮
- 可以在该按钮中添加各种实用功能,列出很多选项按钮,需要安装支持库,这里涉及到一个名为flutter speed dial的库,这个需要安装,可前往这个网址参看指导:flutter speed dial
- 试举例如下:
import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo'),
),
body: Center(
child: Text("Hello World"),
),
floatingActionButton: SpeedDial(
icon: Icons.share,
backgroundColor: Colors.amber,
children: [
SpeedDialChild(
child: Icon(Icons.face),
label: 'Social Network',
backgroundColor: Colors.amberAccent,
onTap: () {/* Do someting */},
),
SpeedDialChild(
child: Icon(Icons.email),
label: 'Email',
backgroundColor: Colors.amberAccent,
onTap: () {/* Do something */},
),
SpeedDialChild(
child: Icon(Icons.chat),
label: 'Message',
backgroundColor: Colors.amberAccent,
onTap: () {/* Do something */},
),
]),
);
}
}
生成效果如下图所示:

- 我的微信
- 微信扫一扫加好友
-
- 我的微信公众号
- 扫描关注公众号
-







