Flutter use reusable method in class - flutter

I am new to flutter, I want to create classes that encompass some functionality of my code. Example here, I have a class that manages my notifications.
As you can see I set the status of my notifications to be able to use them more easily. I have a success status, an error, etc ... but for now I have to rewrite all the code in each method.
How do I set the appearance of a default notification and then inject this code into my methods? In each method I want to be able to change the title and description but I don't want to change the colors manually. They must be defined in my method.
My class :
import 'package:flutter/material.dart';
import 'package:flushbar/flushbar.dart';
import 'package:app/utils/colors.dart';
class MyInfoBar extends Flushbar {
final String title;
final String description;
MyInfoBar({
#required this.title,
#required this.description,
});
Future information(BuildContext context)
{
return Flushbar(
flushbarPosition: FlushbarPosition.TOP,
duration: Duration(seconds: 3),
icon: Icon(
Icons.info_outline,
size: 28.0,
color: Colors.white,
),
shouldIconPulse : false,
backgroundColor: MyColors.colorContrastPurple,
titleText: Text(title, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, color: Colors.white)),
messageText: Text(description, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0, color: Colors.white)),
).show(context);
}
Future success(BuildContext context)
{
return Flushbar(
flushbarPosition: FlushbarPosition.TOP,
duration: Duration(seconds: 3),
icon: Icon(
Icons.check_circle_outline,
size: 28.0,
color: Colors.white,
),
shouldIconPulse : false,
backgroundColor: MyColors.colorContrastGreen,
titleText: Text(title, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, color: Colors.white)),
messageText: Text(description, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0, color: Colors.white)),
).show(context);
}
Future error(BuildContext context)
{
return Flushbar(
flushbarPosition: FlushbarPosition.TOP,
duration: Duration(seconds: 3),
icon: Icon(
Icons.error_outline,
size: 28.0,
color: Colors.white,
),
shouldIconPulse : false,
backgroundColor: MyColors.colorContrastRed,
titleText: Text(title, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, color: Colors.white)),
messageText: Text(description, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0, color: Colors.white)),
).show(context);
}
}
And when I want to use it :
MyInfoBar(title: "title", description: "description",).information(context);
Is this the right way to go?

You are almost there!
class MyInfoBar extends Flushbar {
// No need to store the values
MyInfoBar({
#required String title,
#required String description,
FlushbarPosition flushbarPosition = FlushbarPosition.TOP, // This is a default value. If you do not pass this property to the constructor, FlushbarPosition.TOP will be considered
Duration duration = const Duration(seconds: 3), // Same here but notice the const keyword. This is because default values should always be constant
bool shouldIconPulse = false,
// Other properties here and their default values. If you specify no default value, they will be null.
}) : super( // Now send these properties to the parent which is Flushbar
titleText: Text(title), // add default styling if you want
messageText: Text(description),
duration: duration,
shouldIconPulse: shouldIconPulse,
// Etc.
);
// So what we are doing here is creating a Flushbar with some default properties and naming it MyInfoBar.
// Now whenever you instantiate MyInfoBar, you get the default notification and you can of course adjust the properties.
// Static methods are cleaner in this context as in your example,
// you are instantiating this class but only using it to instantiate
// a new Flushbar thus eliminating the purpose of the first object you created.
static Future success({
#required String title,
#required String description,
#required BuildContext context
}) {
return MyInfoBar(title: title, description: description).show(context); // Other properties get the default values as you have not specified any here.
}
// Similarly you can define other methods.
}
Now to access it:
MyInfoBar.success(title: "Hello World", description: "Beep boop!", context: context);
I wrote this code here directly so there may be some typos but, I hope you get the idea.

Related

How to add textstyle in global class using flutter [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
class CATextStyle extends TextStyle {
static const style = TextStyle();
//const CATextStyle._(TextStyle style) : super(style);
CATextStyle._style(TextStyle style) : super(style);
}
abstract class CATextStyles {
static const _parent = TextStyle();
static final headLine1 =
CATextStyle._style(_parent.copyWith(color: Colors.amber));
}
I want to created class like this but is showing error
i want to know how to use only one textstyle class and reuse that using copywith method
Here is how I do this, Create a separate Directory and name it Constants and inside this create a dart file with the name appstyles.dart. In this class declare all your styles just like the below code.
class AppStyles{
static TextStyle headline1 = TextStyle(
fontFamily: 'Roboto',
fontWeight: FontWeight.w300,
fontSize: 40,
);
static const TextStyle headline2 = TextStyle(
fontWeight: FontWeight.w400,
fontSize: 30,
);
static const TextStyle bodyText1 = TextStyle(
fontWeight: FontWeight.w300,
color: Colors.black,
fontSize: 16,
);
static const TextStyle bodyText2 = TextStyle(
color: Colors.black,
fontWeight: FontWeight.w300,
fontSize: 14,
);
}
The same is you use for Container decoration etc e.g
static final kRoundedTContainer = BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.all(
Radius.circular(10),
));
And here is how to use these styles
Text(
'Hello World',
style: AppStyles.headline1,
)
Container(
decoration: AppStyles.kRoundedTContainer,
height: 200,
width: 200,
)
You can create TextStyle global class like this.
class CommonFontStyle {
static font12WithRegular({color}) {
return TextStyle(
fontSize: Dimensions.fontSize12,
fontFamily: 'Montserrat Regular',
fontWeight: FontWeight.w500,
color: color);
}
static font12WithMedium({weight}) {
return TextStyle(
fontSize: Dimensions.fontSize12,
fontFamily: 'Montserrat Medium',
fontWeight: weight,
);
}
}
and for use of this you have to add simply this font12WithRegular() to your textStyles.
child: Text(
"Okay",
style: CommonFontStyle.font12WithRegular(),
textAlign: TextAlign.center,
),

The argument type 'String?' can't be assigned to the parameter type 'String' because 'String?' is nullable and 'String' isn't in Text widget

I am trying to display the name and email of the person when he logs in to the profile screen using Getx
Column(
children: [
Text(
controller.userModel!.name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Kprimarycolor,
),
),
Text(
controller.userModel!.email,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Kprimarycolor,
),
),
],
),
],
but this error keep showing Error in vs code
and Error in terminal
the related code to name and email is
class UserModel {
late String? userId, email, name, pic;
UserModel({
required this.userId,
required this.email,
required this.name,
required this.pic,
});
UserModel.fromJson(Map<dynamic, dynamic> map) {
userId = map['userId'];
email = map['email'];
name = map['name'];
pic = map['pic'];
}
toJson() {
return {
'userId': userId,
'email': email,
'name': name,
'pic': pic,
};
}
}
I tried to add .toString() and as String but the error keeps showing after debugging
Column(
children: [
Text(
controller.userModel!.name!,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Kprimarycolor,
),
),
Text(
controller.userModel!.email!,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Kprimarycolor,
),
),
],
),
],
I added '!' character, it should work.
In your model, late String? userId, email, name, pic; and #Salih Can answer will be work.
Here, String? means string can accept null value. But Text widget don't accept null value. You need to use bang operator ! to handle it and by adding ! means this value is not null anymore. A better practice would be checking if it is null or not, then assign on Text. It can be
Text(myVal==null? "defalut value": myVal)
Text(myVal??"default Value")
if(myval!=null) Text(myVal) and it will render only if string is not null.

Flutter assign Theme text style

I was wondering is there is a better way to assign a certain default text style of my Theme to a Text widget than this approach.
Text(
'Hello world',
style: Theme.of(context).textTheme.headline1,
),
I did assume there should be something like a separate Widget or a Text Method Text.headline1 or simply a style Command style: TextStyle.headline1.
But seems I have to go through the Theme.of(context) to get this.
Does anyone have a better solution?
I think yon can't escape some boilerplate. For me this approach looks cleanest
import 'package:flutter/material.dart';
class StyledText extends StatelessWidget {
final String text;
late final TextStyle? Function(BuildContext context)? getStyle;
StyledText.headline1(this.text, {Key? key}) : super(key: key) {
getStyle = (context) {
return Theme.of(context).textTheme.headline1;
};
}
StyledText.headline2(this.text, {Key? key}) : super(key: key) {
getStyle = (context) {
return Theme.of(context).textTheme.headline2;
};
}
// ...
#override
Widget build(BuildContext context) {
return Text(text, style: getStyle?.call(context));
}
}
And use the widget like this
StyledText.headline1("Hello world");
Theme.of returns the ThemeData value specified for the nearest BuildContext ancestor. If you don't use it, then you won't be able to access the theme configuration you may set and benefit from its advantages.
However, you can create a class called Styles where you can access the pre-defined colors, text styles and more:
class Styles {
static const Color primaryColor = Colors.blue;
static const TextStyle headline1 = TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
);
static const TextStyle bodyText1 = TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.normal,
);
}
Here is an example of using it:
Text(
'Hello world',
style: Styles.headline1,
)
You define all Your Theme Style in Main like this
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.purple,
textTheme: TextTheme(
headline1: TextStyle(
color: const Color(0xFF232323),
fontSize: 26.sp,
fontWeight: FontWeight.w500,
fontFamily: "Mont Regular",
),
),
)
Then use like this
Text("A cloud-agnostic solution for Project and HR Management",
style: Theme.of(context).textTheme.headline1)
You can use TextStyle directly:
Text(
'Hello world',
style: TextStyle(color: Colors.black, fontSize: 15.0), // Etc...
),
Theme.of(context) is a great way to go for a variety of reasons, like switching between light and dark themes. I like to create a variable for the theme and text theme to keep things clean and efficient.
Widget build(BuildContext context) {
final theme = Theme.of(context);
final textTheme = theme.textTheme;
return Column(
children: [
Text('Heading Text', style: textTheme.headline1),
Text('Caption Text', style: textTheme.caption),
Text('Body text...', style: textTheme.bodyText1),
],
);
}

Can a single TextField in flutter have variable line height?

I'm implementing a simple rich text editor that renders text with a text editing controller that recognises basic markdown syntax, I'll link some code down below.
Everything works fine, the only problem I'm having is when a text style requires a bigger line height, for instance an # h1 that should be rendered as a title and therefore require a bigger line height overlaps over the previous line, as you can see in the screenshot below.
I've not been able so far to make the line height in a TextView variable based on the style of the text that is being displayed, is such thing even achievable in a Flutter TextView?
Here's a snippet of my text editing controller and a screenshot detailing my problem.
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class AddNotePage extends StatelessWidget {
final TextEditingController _controller = MarkdownTextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add Note'),
),
body: GestureDetector(
onVerticalDragDown: (_) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: TextField(
style: defaultTextStyle,
controller: _controller,
decoration: InputDecoration(
hintText: "Insert your message",
border: UnderlineInputBorder(
borderSide: BorderSide.none,
),
),
scrollPadding: EdgeInsets.all(20.0),
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
],
),
),
);
}
}
const Map<String, TextStyle> defaultMarkdownStyleMap = {
r'^# .*?$': TextStyle(
fontWeight: FontWeight.bold,
fontSize: 50,
),
r'^## .*?$': TextStyle(
fontWeight: FontWeight.bold,
fontSize: 40,
),
r'^### .*?$': TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
),
r'__(.*?)\__': TextStyle(fontStyle: FontStyle.italic, fontSize: 20),
r'~~(.*?)~~': TextStyle(decoration: TextDecoration.lineThrough, fontSize: 20),
r'\*\*(.*?)\*\*': TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
};
const TextStyle defaultTextStyle = TextStyle(fontSize: 20);
class MarkdownTextEditingController extends TextEditingController {
final Map<String, TextStyle> styleMap;
final Pattern pattern;
MarkdownTextEditingController({this.styleMap = defaultMarkdownStyleMap})
: pattern = RegExp(
styleMap.keys.map((key) {
return key;
}).join('|'),
multiLine: true);
#override
TextSpan buildTextSpan(
{required BuildContext context,
TextStyle? style,
required bool withComposing}) {
final List<InlineSpan> children = [];
text.splitMapJoin(
pattern,
onMatch: (Match match) {
TextStyle? markdownStyle = styleMap[styleMap.keys.firstWhere(
(e) {
return RegExp(e).hasMatch(match[0]!);
},
)];
children.add(TextSpan(
text: match[0],
style: style!.merge(markdownStyle),
));
return "";
},
onNonMatch: (String text) {
children
.add(TextSpan(text: text, style: style!.merge(defaultTextStyle)));
return "";
},
);
return TextSpan(style: style, children: children);
}
}
I've found a solution.
All I needed to do was to play around with the strutStyle property of the TextField.
As the documentation states:
The strut style used for the vertical layout.
StrutStyle is used to establish a predictable vertical layout. Since
fonts may vary depending on user input and due to font fallback,
StrutStyle.forceStrutHeight is enabled by default to lock all lines to
the height of the base TextStyle, provided by style. This ensures the
typed text fits within the allotted space.

How to write a function (in flutter-dart) so that it accepts certain parameters when we call that function?

This is my code:
Text ButtonText = Text(
_buttonText, style: TextStyle(
color: Colors.white,
fontFamily: 'San francisco',
//fontSize: 21.0.ssp,
letterSpacing: 2.0,
wordSpacing: 2.0
),
);
when I use this Text in my button widget, I want to set font size explicitly. How can I do that?
you can create a class for your situation we can call it customtext
here is an example code :
import 'package:flutter/material.dart';
class CustomText extends StatelessWidget {
final String text;
final double size;
final Color color;
final FontWeight weight;
// name constructor that has a positional parameters with the text required
// and the other parameters optional
CustomText({#required this.text, this.size,this.color,this.weight});
#override
Widget build(BuildContext context) {
return Text(
text,style: TextStyle(fontSize: size ?? 16, color: color ?? Colors.black, fontWeight: weight ?? FontWeight.normal),
);
}
}