Flutter:RichText 未按预期工作
Flutter: RichText not working as expected
我是 Flutter 的新手,正在尝试克隆一个应用程序来学习它。我在真实应用程序中创建了一个像这样的介绍:introduction screen in real app
我使用 RichText
创建该文本,但它以某种方式在屏幕上显示了代码:introduction screen in my clone app
代码如下:
class Body extends StatefulWidget {
const Body({Key? key}) : super(key: key);
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
int currentPage = 0;
final List<Map<String, Object>> _introductionData = [
{
"image": "assets/images/intro_1.png",
"title": "",
"text": RichText(
text: const TextSpan(
style: TextStyle(
fontSize: 12,
color: Colors.white,
),
children: [
TextSpan(
text: 'Sign in first time ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'success to get '),
TextSpan(
text: '50% off coupon ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'and '),
TextSpan(
text: 'lottery code ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'to join '),
TextSpan(
text: '"Download app, get big prize" ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'have a chance '),
TextSpan(
text: 'to win a smart tv ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'worth nearly 1000$.')
],
),
),
},
{
"image": "assets/images/intro_2.png",
"title": "Super convenient online pharmacy",
"text": 'Full of great deals, free shipping from 13$. Accumulate Extracare points after every purchase.',
},
{
"image": "assets/images/intro_3.png",
"title": "Consult with a pharmacist online via video.",
"text": 'Advice on prescriptions and drug use from a team of highly qualified pharmacists.'
},
{
"image": "assets/images/intro_4.png",
"title": "Look up drug information and disease symptoms",
"text": 'Update the latest health information, look up information quickly and accurately.',
},
];
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
child: Stack(
fit: StackFit.expand,
children: [
Image.asset(
'assets/images/intro_background.png',
fit: BoxFit.cover,
height: double.infinity,
alignment: Alignment.topCenter,
),
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 16.0),
child: Column(
children: [
Expanded(
flex: 6,
child: PageView.builder(
onPageChanged: (value) {
setState(() {
currentPage = value;
});
},
itemCount: _introductionData.length,
itemBuilder: (context, index) => IntroductionContent(
image: _introductionData[index]['image'].toString(),
title: _introductionData[index]['title'].toString(),
text: _introductionData[index]['text'].toString(),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
_introductionData.length,
(index) => buildDot(index: index),
),
),
const Padding(padding: EdgeInsets.only(top: 25)),
DefaultButton(
text: 'Continue',
backgroundColor: Colors.white,
textColor: kPrimaryColor,
press: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext _context) =>
const AcceptTermsScreen(),
),
);
},
)
],
),
),
)
],
),
),
],
),
);
}
AnimatedContainer buildDot({int? index}) {
return AnimatedContainer(
duration: kAnimationDuration,
margin: const EdgeInsets.only(right: 15),
height: currentPage == index ? 6 : 4,
width: currentPage == index ? 6 : 4,
decoration: BoxDecoration(
color: currentPage == index
? Colors.white
: const Color(0x77FFFFFF),
borderRadius: BorderRadius.circular(3),
),
);
}
}
简介内容代码:
class IntroductionContent extends StatelessWidget {
const IntroductionContent({
Key? key,
this.title,
this.text,
this.image,
}) : super(key: key);
final String? title, text, image;
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
const Spacer(),
const Spacer(),
Image.asset(
image!,
height: 250,
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Text(
title!,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white,
),
),
),
const Padding(padding: EdgeInsets.only(top: 20)),
Text(
text!,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 12,
color: Colors.white,
height: 1.5,
),
),
],
);
}
}
在此先感谢您帮我解决这个问题。
将您的文本类型字符串更改为 RichText,并在您的 pageView 中,从 IntroductionContent
文本参数中删除 toString
。
PageView.build
PageView.builder(
onPageChanged: (value) {
setState(() {
currentPage = value;
});
},
itemCount: _introductionData.length,
itemBuilder: (context, index) => IntroductionContent(
image: _introductionData[index]['image'].toString(),
title: _introductionData[index]['title'].toString(),
text: _introductionData[index]['text'], // here changed need
),
),
IntroductionContent.class
class IntroductionContent extends StatelessWidget {
const IntroductionContent({
Key key,
this.title,
this.text,
this.image,
}) : super(key: key);
final String title, image;
final RichText text; // change text string to Richtext
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
const Spacer(),
const Spacer(),
Image.asset(
image,
height: 250,
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Text(
title,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white,
),
),
),
const Padding(padding: EdgeInsets.only(top: 20)),
text, // here just assign your text
],
);
}
}
输出:
我是 Flutter 的新手,正在尝试克隆一个应用程序来学习它。我在真实应用程序中创建了一个像这样的介绍:introduction screen in real app
我使用 RichText
创建该文本,但它以某种方式在屏幕上显示了代码:introduction screen in my clone app
代码如下:
class Body extends StatefulWidget {
const Body({Key? key}) : super(key: key);
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
int currentPage = 0;
final List<Map<String, Object>> _introductionData = [
{
"image": "assets/images/intro_1.png",
"title": "",
"text": RichText(
text: const TextSpan(
style: TextStyle(
fontSize: 12,
color: Colors.white,
),
children: [
TextSpan(
text: 'Sign in first time ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'success to get '),
TextSpan(
text: '50% off coupon ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'and '),
TextSpan(
text: 'lottery code ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'to join '),
TextSpan(
text: '"Download app, get big prize" ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'have a chance '),
TextSpan(
text: 'to win a smart tv ',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
TextSpan(text: 'worth nearly 1000$.')
],
),
),
},
{
"image": "assets/images/intro_2.png",
"title": "Super convenient online pharmacy",
"text": 'Full of great deals, free shipping from 13$. Accumulate Extracare points after every purchase.',
},
{
"image": "assets/images/intro_3.png",
"title": "Consult with a pharmacist online via video.",
"text": 'Advice on prescriptions and drug use from a team of highly qualified pharmacists.'
},
{
"image": "assets/images/intro_4.png",
"title": "Look up drug information and disease symptoms",
"text": 'Update the latest health information, look up information quickly and accurately.',
},
];
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
child: Stack(
fit: StackFit.expand,
children: [
Image.asset(
'assets/images/intro_background.png',
fit: BoxFit.cover,
height: double.infinity,
alignment: Alignment.topCenter,
),
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 16.0),
child: Column(
children: [
Expanded(
flex: 6,
child: PageView.builder(
onPageChanged: (value) {
setState(() {
currentPage = value;
});
},
itemCount: _introductionData.length,
itemBuilder: (context, index) => IntroductionContent(
image: _introductionData[index]['image'].toString(),
title: _introductionData[index]['title'].toString(),
text: _introductionData[index]['text'].toString(),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
_introductionData.length,
(index) => buildDot(index: index),
),
),
const Padding(padding: EdgeInsets.only(top: 25)),
DefaultButton(
text: 'Continue',
backgroundColor: Colors.white,
textColor: kPrimaryColor,
press: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext _context) =>
const AcceptTermsScreen(),
),
);
},
)
],
),
),
)
],
),
),
],
),
);
}
AnimatedContainer buildDot({int? index}) {
return AnimatedContainer(
duration: kAnimationDuration,
margin: const EdgeInsets.only(right: 15),
height: currentPage == index ? 6 : 4,
width: currentPage == index ? 6 : 4,
decoration: BoxDecoration(
color: currentPage == index
? Colors.white
: const Color(0x77FFFFFF),
borderRadius: BorderRadius.circular(3),
),
);
}
}
简介内容代码:
class IntroductionContent extends StatelessWidget {
const IntroductionContent({
Key? key,
this.title,
this.text,
this.image,
}) : super(key: key);
final String? title, text, image;
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
const Spacer(),
const Spacer(),
Image.asset(
image!,
height: 250,
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Text(
title!,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white,
),
),
),
const Padding(padding: EdgeInsets.only(top: 20)),
Text(
text!,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 12,
color: Colors.white,
height: 1.5,
),
),
],
);
}
}
在此先感谢您帮我解决这个问题。
将您的文本类型字符串更改为 RichText,并在您的 pageView 中,从 IntroductionContent
文本参数中删除 toString
。
PageView.build
PageView.builder(
onPageChanged: (value) {
setState(() {
currentPage = value;
});
},
itemCount: _introductionData.length,
itemBuilder: (context, index) => IntroductionContent(
image: _introductionData[index]['image'].toString(),
title: _introductionData[index]['title'].toString(),
text: _introductionData[index]['text'], // here changed need
),
),
IntroductionContent.class
class IntroductionContent extends StatelessWidget {
const IntroductionContent({
Key key,
this.title,
this.text,
this.image,
}) : super(key: key);
final String title, image;
final RichText text; // change text string to Richtext
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
const Spacer(),
const Spacer(),
Image.asset(
image,
height: 250,
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Text(
title,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white,
),
),
),
const Padding(padding: EdgeInsets.only(top: 20)),
text, // here just assign your text
],
);
}
}
输出: