《Flutter实战·第二版》
Text
- TextAlign:left right center 注意点:对齐的参考系是Text widget 本身,如果文本不够长,设置看起来是没有生效的;文本长才看得到,字符串内容超过一行,Text 宽度等于屏幕宽度,第二行文本便会居中显示。
- maxLines、overflow:指定文本显示的最大行数,默认情况下,文本是自动折行的,如果指定此参数,则文本最多不会超过指定的行。此处截断方式TextOverflow.ellipsis,它会将多余文本截断后以省略符“...”表示;
- textScaler:字体大小,TextScaler.linear(1.5);TextScaler.noScaling则是:禁止部分文本随系统字体大小缩放
const Text("Hello worldaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",textAlign: TextAlign.right,
),
Text("Hello world! I'm Jack. "*4,maxLines: 1,overflow: TextOverflow.ellipsis,
),
const Text("Hello world",// textScaler: TextScaler.noScaling,textScaler: TextScaler.linear(1.5),
),
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';// import 'package:flutter/cupertino.dart';
// void main() {
// runApp(const MyApp());
// }import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;void main() => runApp(const MyApp());
// void main() => runApp(CupertinoApp(home: CupertinoTestRoute()));class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',initialRoute:"/", //名为"/"的路由作为应用的home(首页)theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),useMaterial3: true,),routes:{"new_page":(context) => TipRoute(text:'这个参数是配置路由传过来的'),"/":(context) => RouterTestRoute(), //注册首页路由},);}
}class TipRoute extends StatelessWidget {TipRoute({Key? key,required this.text, // 接收一个text参数}) : super(key: key);final String text;// Future<String> loadAsset() async {// return await rootBundle.loadString('assets/my_icon.png');// }@overrideWidget build(BuildContext context) {//获取路由参数var args=ModalRoute.of(context)?.settings.arguments;print('旧页面传递参数的方法2:arguments:$args');return Scaffold(appBar: AppBar(title: Text("提示"),),body: Padding(padding: EdgeInsets.all(18),child: Center(child: Column(children: <Widget>[Text(text),ElevatedButton(onPressed: () => Navigator.pop(context, "这个数据是新页面传递给旧页面的"),child: Text("返回"),),// AssetImage(loadAsset())// Image.asset('assets/my_icon.png'),],),),),);}
}// flutter run -d chrome --web-renderer canvaskit
class RouterTestRoute extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("初始页面"),),body: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [ElevatedButton(onPressed: () async {// 打开`TipRoute`,并等待返回结果// var result = await Navigator.push(// context,// MaterialPageRoute(// builder: (context) {// return TipRoute(// // 路由参数// text: "这个数据是旧页面传递给新页面的",// );// },// ),// );var result = await Navigator.pushNamed(context, "new_page", arguments: "hi");//输出`TipRoute`路由返回结果print("路由返回值: $result");},child: Text("打开提示页"),),RandomWordsWidget(),const Text("Hello world",textAlign: TextAlign.right,),Text("Hello world! I'm Jack. "*4,maxLines: 1,overflow: TextOverflow.ellipsis,),const Text("Hello world",// textScaler: TextScaler.noScaling,textScaler: TextScaler.linear(1.5),),],),);}
}class RandomWordsWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {// 生成随机字符串final wordPair = WordPair.random();return Padding(padding: const EdgeInsets.all(8.0),child: Text('这是随机的英文字符串:' + wordPair.toString()),);}
}
TextStyle
- height:该属性用于指定行高,但它并不是一个绝对值,而是一个因子,具体的行高等于fontSize*height。
- fontFamily :由于不同平台默认支持的字体集不同,所以在手动指定字体时一定要先在不同平台测试一下。
- fontSize:该属性和 Text 的textScaler都用于控制字体大小。但是有两个主要区别:
- fontSize可以精确指定字体大小,而textScaler只能通过缩放比例来控制。
- textScaler主要是用于系统字体大小设置改变时对 Flutter 应用字体进行全局调整,而fontSize通常用于单个文本,字体大小不会跟随系统字体大小变化
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';// import 'package:flutter/cupertino.dart';
// void main() {
// runApp(const MyApp());
// }import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;void main() => runApp(const MyApp());
// void main() => runApp(CupertinoApp(home: CupertinoTestRoute()));class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',initialRoute:"/", //名为"/"的路由作为应用的home(首页)theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),useMaterial3: true,),routes:{"new_page":(context) => TipRoute(text:'这个参数是配置路由传过来的'),"/":(context) => RouterTestRoute(), //注册首页路由},);}
}class TipRoute extends StatelessWidget {TipRoute({Key? key,required this.text, // 接收一个text参数}) : super(key: key);final String text;// Future<String> loadAsset() async {// return await rootBundle.loadString('assets/my_icon.png');// }@overrideWidget build(BuildContext context) {//获取路由参数var args=ModalRoute.of(context)?.settings.arguments;print('旧页面传递参数的方法2:arguments:$args');return Scaffold(appBar: AppBar(title: Text("提示"),),body: Padding(padding: EdgeInsets.all(18),child: Center(child: Column(children: <Widget>[Text(text),ElevatedButton(onPressed: () => Navigator.pop(context, "这个数据是新页面传递给旧页面的"),child: Text("返回"),),// AssetImage(loadAsset())// Image.asset('assets/my_icon.png'),],),),),);}
}// flutter run -d chrome --web-renderer canvaskit
class RouterTestRoute extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("初始页面"),),body: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [ElevatedButton(onPressed: () async {// 打开`TipRoute`,并等待返回结果// var result = await Navigator.push(// context,// MaterialPageRoute(// builder: (context) {// return TipRoute(// // 路由参数// text: "这个数据是旧页面传递给新页面的",// );// },// ),// );var result = await Navigator.pushNamed(context, "new_page", arguments: "hi");//输出`TipRoute`路由返回结果print("路由返回值: $result");},child: Text("打开提示页"),),RandomWordsWidget(),Text("Hello worldaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",textAlign: TextAlign.right,style: TextStyle(color: Colors.blue,fontSize: 18.0,height: 1.2,fontFamily: "Courier",background: Paint()..color=Colors.yellow,decoration:TextDecoration.underline,decorationStyle: TextDecorationStyle.dashed),),// Text("Hello world! I'm Jack. "*4,// maxLines: 1,// overflow: TextOverflow.ellipsis,// ),// const Text("Hello world",// // textScaler: TextScaler.noScaling,// textScaler: TextScaler.linear(1.5),// ),],),);}
}class RandomWordsWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {// 生成随机字符串final wordPair = WordPair.random();return Padding(padding: const EdgeInsets.all(8.0),child: Text('这是随机的英文字符串:' + wordPair.toString()),);}
}
TextSpan
通过 TextSpan 实现了一个基础文本片段和一个链接片段,然后通过Text.rich 方法将TextSpan 添加到 Text 中, Text 其实就是 RichText 的一个包装,而RichText 是可以显示多种样式(富文本)的 widget。
Text.rich(TextSpan(children: [TextSpan(text: 'home:'),TextSpan(text: 'https://aaa.bbb.com',style: TextStyle(color: Colors.blue,fontSize: 20,),// recognizer: _tapRecognizer)]
))
DefaultTextStyle
如果使用DefaultTextStyle在 Widget 树的某一个节点处设置一个默认的文本样式,那么该节点的子树中所有文本都会默认使用这个样式,不使用的话要inherit: false;不过我试了只要子树设置了style 不写inherit: false也没事
class RouterTestRoute extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("初始页面"),),body: DefaultTextStyle(style: const TextStyle(color:Colors.red,fontSize: 20.0,),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [ElevatedButton(onPressed: () async {// 打开`TipRoute`,并等待返回结果// var result = await Navigator.push(// context,// MaterialPageRoute(// builder: (context) {// return TipRoute(// // 路由参数// text: "这个数据是旧页面传递给新页面的",// );// },// ),// );var result = await Navigator.pushNamed(context, "new_page", arguments: "hi");//输出`TipRoute`路由返回结果print("路由返回值: $result");},child: Text("打开提示页"),),RandomWordsWidget(),Text("Hello worldaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",textAlign: TextAlign.right,// style: TextStyle(// color: Colors.blue,// fontSize: 18.0,// height: 1.2,// fontFamily: "Courier",// background: Paint()..color=Colors.yellow,// decoration:TextDecoration.underline,// decorationStyle: TextDecorationStyle.dashed// ),),Text('这句话不继承默认样式',style: TextStyle(inherit: false,color: Colors.green,fontSize: 20,),)// Text.rich(TextSpan(// children: [// TextSpan(// text: 'home:'// ),// TextSpan(// text: 'https://aaa.bbb.com',// style: TextStyle(// color: Colors.blue,// fontSize: 20,// ),// // recognizer: _tapRecognizer// )// ]// ))// Text("Hello world! I'm Jack. "*4,// maxLines: 1,// overflow: TextOverflow.ellipsis,// ),// const Text("Hello world",// // textScaler: TextScaler.noScaling,// textScaler: TextScaler.linear(1.5),// ),],),));}
}
字体
可以在 Flutter 应用程序中使用不同的字体
在 Flutter 中使用字体分两步完成。首先在pubspec.yaml中声明它们,以确保它们会打包到应用程序中。然后通过TextStyle (opens new window)属性使用字体。
在pubspec.yaml中声明
flutter:# The following line ensures that the Material Icons font is# included with your application, so that you can use the icons in# the material Icons class.uses-material-design: truefonts:- family: Ralewayfonts:- asset: lib/assets/fonts/Raleway/Raleway-LightItalic.ttfweight: 300style: italic- family: MiaoZifonts:- asset: lib/assets/fonts/MiaoZi-YunYingTi-2.ttf
使用:
Text('这句话使用了喵喵字体',style: TextStyle(inherit: false,fontFamily: 'MiaoZi',color: Colors.blue,fontSize: 30,// fontWeight: FontWeight.w300,// fontStyle: FontStyle.italic,),
不太会用的话可以看看这个视频