i'm trying to display the old and the new price inside of a RichText.
if(regularPrice >= discountPrice){
TextSpan(
text: ' $regularPrice',
style: TextStyle(
decoration: TextDecoration.lineThrough,
decorationThickness: 2.85,
fontSize: 15,
ontWeight: FontWeight.bold),
),
TextSpan(
text: ' $discountPrice',
style: TextStyle(
fontSize: 15,
ontWeight: FontWeight.bold),
),
}else{
TextSpan(
text: ' $regularPrice',
style: TextStyle(
fontSize: 15,
ontWeight: FontWeight.bold),
),
}
Can i use this logic inside a RichText?
You can use the spread operator:
class RichTextDiscountedPrice extends StatelessWidget {
static const regularPrice = 100;
static const discountedPriced = 95;
#override
Widget build(BuildContext context) {
final regularPriceTextSpan = TextSpan(text: ' $discountedPriced', style: TextStyle(fontWeight: FontWeight.bold));
final discountedTextSpanList = [
TextSpan(text: '$regularPrice', style: TextStyle(decoration: TextDecoration.lineThrough)),
regularPriceTextSpan
];
return Center(
child: RichText(
text: TextSpan(
text: "Price ",
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
if (regularPrice > discountedPriced) ...discountedTextSpanList else ...<TextSpan>[regularPriceTextSpan],
],
),
),
);
}
}
Note: I edited the styles a little to reduce the number of lines for the example.
Related
I want to make specific letter to have a custom font or style in Flutter, is it possible to do that? I only saw tutorial on how to make specific word in Flutter to have custom style by using RichText. Is there anyway to make a specific letter instead of a word?
for example
𝒜n elephant
In this case the letter A will have a custom font but the letter n does not.
The text parameter in a TextSpan can be omitted. So for what you want, you can just use the children parameter and have the first child be a single character.
RichText(
text: TextSpan(
children: [
TextSpan(
text: 'L',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
const TextSpan(text: 'ike this?')
],
),
),
You can do like this :
Text.rich(
TextSpan(text: 'This is textspan ', children: <InlineSpan>[
TextSpan(
text: 'Widget in flutter',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
)
]),
)
You can customize it any way you want :D
String myString = "Helloooo";
String specialChar = "o";
RichText(
text: TextSpan(
children: myString.characters.map((e) {
return TextSpan(
text: e,
style: e == specialChar
? TextStyle(
color: Colors.red, fontWeight: FontWeight.bold, fontSize: 40)
: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold, fontSize: 50),
);
}).toList()));
in my flutter book app, I fetch a text from a JSON object and display it in PageView.builder. and after it fetches and displays on the first page and when it goes to the next page it duplicates the first page instead of displaying the remaining text file.
Container(
height: height,
width: width,
child: PageView.builder(
itemBuilder: (context, index){
return RichText(
textDirection: TextDirection.rtl,
text: TextSpan(
text: '',
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
for (var i = 1; i <= count; i++) ...{
TextSpan(
text: quran.getVerse(widget.id, i, verseEndSymbol: false),
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
fontFamily: 'kitab'),
),
TextSpan(
text: quran.getVerseEndSymbol(i),
style: TextStyle(
color: Colors.cyanAccent,
fontSize: 26,
fontWeight: FontWeight.bold,
fontFamily: 'kitab',
),
),
}
],
),
);
}),
);
how can I split those text and display it on a page?
I have to know how many lines are fitting in a Text with given size and TextStyle.
I played around with TextPainter but this does only provide information if the max lines are exceeded but not what's the last char index of the string that fits into it.
Usecase:
I have to split a string into multiple Text widgets which have a fixed size ands text style.
I'm not sure if this is what you want, but you can use TextSpan for different styles for your text.
Here is an example:
import 'package:flutter/material.dart';
class TextSpanExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "TextSpan number 1",
style: TextStyle(
color: Colors.black,
fontSize: 14,
),
),
TextSpan(
text: "TextSpan number 2",
style: TextStyle(
color: Colors.red,
fontSize: 18,
fontWeight: FontWeight.bold
),
),
TextSpan(
text: "TextSpan number 3",
style: TextStyle(
color: Colors.green,
fontSize: 16,
),
),
]
),
),
),
);
}
}
There is a random list whose length is not constant. For example
List<String> exampleList = List<String>();
exampleList.add("one");
exampleList.add("second random line");
exampleList.add("third random line");
Depending on the content of the exampleList[index], which is generated randomly, it is necessary to change the appearance, design, styles etc. If you use RichText TextSpan, then already hardcoded data is transferred there, and I need to generate this RichText dynamically. Any ideas on this?
approximate result of formating
child: RichText(
text: TextSpan(
text: 'GitHub is a development platform inspired by the way you work. From ',
style: TextStyle(
color: Colors.grey,
fontSize: 20,
),
children: <TextSpan>[
TextSpan(text: 'op_n',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
recognizer: TapGestureRecognizer()
..onTap = () {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Sending Message"),
));
}
),
TextSpan(
text: ' to ',
style: TextStyle(color: Colors.grey,
fontSize: 20,
)
),
TextSpan(
text: 'busin_ss,',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
recognizer: TapGestureRecognizer()
..onTap = () {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Sending Message"),
));
}
),
TextSpan(
text: ' you can host and review code, manage projects, and build software alongside 36 million developers.',
style: TextStyle(color: Colors.grey,
fontSize: 20,
)
)
]
),
)
Based on your sample, I see that you define each part of your RichText with a text, a style, and optionally a callback.
You could use a List<MyText> instead of a List<String>:
class MyText {
final String text;
final TextStyle style;
final void Function(BuildContext) callback;
MyText({
this.text,
this.style,
this.callback,
});
}
List<MyText> textSpanList = [
MyText(
text:
'GitHub is a development platform inspired by the way you work. From ',
style: TextStyle(
color: Colors.grey,
fontSize: 20,
),
),
MyText(
text: 'op_n',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
callback: (context) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Sending Message"),
),
);
},
),
MyText(
text: ' to ',
style: TextStyle(
color: Colors.grey,
fontSize: 20,
),
),
MyText(
text: 'busin_ss,',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
callback: (context) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Sending Message"),
),
);
},
),
MyText(
text:
' you can host and review code, manage projects, and build software alongside 36 million developers.',
style: TextStyle(
color: Colors.grey,
fontSize: 20,
),
),
];
And then use the List<MyText> as follows:
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
title: 'Flutter Demo',
home: Scaffold(body: MyWidget()),
),
);
}
class MyWidget extends StatelessWidget {
const MyWidget({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
color: Colors.black,
padding: const EdgeInsets.all(8.0),
child: RichText(
text: TextSpan(
children: textSpanList
.map(
(data) => data.callback == null
? TextSpan(
text: data.text,
style: data.style,
)
: TextSpan(
text: data.text,
style: data.style,
recognizer: TapGestureRecognizer()
..onTap = () => data.callback(context),
),
)
.toList(),
),
),
);
}
}
I am trying to make only the word "Name:" bold in code below, but am unsure as to the best way to do that. I have tried the "textspan" function and putting the two words on seperate lines but this does not seem to be working.
The original code is below:
ListTile(
leading: Icon(
Icons.book,
color: Colors.grey,
),
title: Text("Name: Timmy",
style: theme.textTheme.body1),
),
You should use RichText with TextSpan like this
Widget build(BuildContext context) {
TextStyle defaultStyle = TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 20.0);
return RichText(
text: TextSpan(
style: defaultStyle,
text: "Name: ",
children: <TextSpan>[
TextSpan(text: 'Timmy', style: TextStyle(fontWeight: FontWeight.normal)),
],
),
);
}
or like this
Widget build(BuildContext context) {
TextStyle defaultStyle = TextStyle(color: Colors.black, fontSize: 20.0);
return RichText(
text: TextSpan(
style: defaultStyle,
children: <TextSpan>[
TextSpan(text: 'Name: ', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: 'Timmy'),
],
),
);
}