I'm using the flutter url_launcher https://pub.dev/packages/url_launcher package to open urls when i click some button.
With the new Link widget im now able to open a web page on the same tab but i cant add mouse pointer when user is hovering the button
import 'package:bianca/UI/botao_azul.dart';
import 'package:url_launcher/link.dart';
import 'package:flutter/material.dart';
String link = "https://www.google.com";
class MesmaAba extends StatelessWidget {
final double tamanho;
final String conteudo;
MesmaAba({this.tamanho, this.conteudo});
#override
Widget build(BuildContext context) {
return Link(
uri: Uri.parse(link),
builder: (BuildContext context, FollowLink followLink) => BotaoAzul(
conteudo: conteudo,
tamanho: tamanho,
funcao: followLink
),
);
}
}
BotaoAzul class:
import 'package:flutter/material.dart';
class BotaoAzul extends StatelessWidget {
final String conteudo;
final double tamanho;
final Function funcao;
BotaoAzul({this.conteudo, this.tamanho,this.funcao});
#override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: FlatButton(
onPressed: funcao,
child: Text(conteudo,
style: TextStyle(
fontSize: tamanho,
color: Colors.white,
fontWeight: FontWeight.bold))),
),
decoration: BoxDecoration(
color: Colors.blue[900], borderRadius: BorderRadius.circular(20.0)),
);
}
}
I can already open urls with botaoAzul button on another tab using this function (and without the Link widget, the mouse changes on hovering the button)
import 'package:url_launcher/url_launcher.dart';
void launchLink(String link) async {
await launch(
link,
);
}
But i need to open the url on the same tab.
I've already tried all implementations of this other question without success:
https://stackoverflow.com/questions/56211844/flutter-web-mouse-hover-change-cursor-to-pointer
As I know latest version of flutter web supports hand cursor for InkWell widget automatically. Below simple class:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
/// Provides an anchor link to web URL.
class HoveredWebAnchor extends StatefulWidget {
HoveredWebAnchor(
{Key key,
#required this.label,
#required this.url,
this.underlined = true})
: assert(label != null),
assert(url != null),
assert(underlined != null),
super(key: key);
/// The label of anchor
final String label;
/// The web URL to open when anchor clicked
final String url;
/// Identifies if anchor label will be underlined.
final bool underlined;
#override
_HoveredWebAnchorState createState() => _HoveredWebAnchorState();
}
class _HoveredWebAnchorState extends State<HoveredWebAnchor> {
/// Current text style
TextStyle _textStyle;
#override
Widget build(BuildContext context) {
return InkWell(
hoverColor: Colors.transparent,
child: Text(
widget.label,
style: _textStyle,
),
onHover: (hovered) {
setState(() {
if (hovered) {
_textStyle = TextStyle(color: Theme.of(context).accentColor);
if (widget.underlined) {
_textStyle = _textStyle.copyWith(
decoration: TextDecoration.underline,
);
}
} else {
_textStyle = null;
}
});
},
onTap: () {
launch(widget.url, forceWebView: true);
},
);
}
}
Using:
HoveredWebAnchor(
label: 'Open Google',
url: 'http://www.google.com',
),
I have improved suggestion of #BambinoUA to sound null safety and some minor changes so I decided to share it with y'all
class HoveredWebAnchor extends StatefulWidget {
const HoveredWebAnchor(
this.label, {
Key? key,
required this.style,
this.maxLines,
required this.onTap,
}) : super(key: key);
final String label;
final TextStyle? style;
final int? maxLines;
final VoidCallback onTap;
#override
_HoveredWebAnchorState createState() => _HoveredWebAnchorState();
}
class _HoveredWebAnchorState extends State<HoveredWebAnchor> {
TextStyle? _textStyle;
#override
void initState() {
_textStyle = widget.style;
super.initState();
}
#override
Widget build(BuildContext context) {
return InkWell(
hoverColor: Colors.transparent,
onHover: (hovered) {
setState(() {
if (hovered) {
_textStyle = _textStyle?.copyWith(
decoration: TextDecoration.underline,
);
} else {
_textStyle = _textStyle?.copyWith(
decoration: widget.style?.decoration,
);
}
});
},
onTap: widget.onTap,
child: Text(
widget.label,
style: _textStyle,
maxLines: widget.maxLines,
),
);
}
}
The way to change your mouse cursor whilst keeping the behavior of the Link Widget the same would be to wrap the Link Widget in a MouseRegion
MouseRegion(
cursor: SystemMouseCursors.click,
child: Link(
uri: Uri.parse(link),
builder: (BuildContext context, FollowLink followLink) =>
BotaoAzul(
conteudo: conteudo,
tamanho: tamanho,
funcao: followLink
),
),
)
From the Link widget revision 2 document:
The Link widget doesn’t provide any mouse cursor, and fully relies on the user to do their own mouse cursor. In many cases, users will be using a button, which already shows the correct mouse cursor. In other cases, the user can wrap the Link (or the child of the Link) in a mouse region and give it a cursor.
found something last night that solves the problem:
Instead of using url_launcher Link, i'm now importing the html package
import 'dart:html' as html;
String link = "https://www.google.com";
.....
void openPage(){
html.window.location.assign(link);
}
...... (widget build method)
BotaoAzul(
conteudo: "Hey",
tamanho: 30,
funcao: openPage
),
It now opens the link on the same tab and i can return to my flutter app from the chrome back button
Related
I need to change implement custom Icons for default button and drawer button for all pages in my project.
I know we have the option of using leading property, however, this only affects that certain page.
How can we change the default back button and open drawer button of AppBar in Flutter for the whole app?
Unfortunately, there is not a property called defaultBackButton or defaultDrawerButton.
So, in order to change these defaults in the whole app, we can create a CustomAppBar which and set Icons as we wish.
Please click here to see Demo on DartPad and test it yourself.
For a bit longer description, checkout my Medium story.
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final Widget? leading;
final Widget? title;
final bool? centerTitle;
final bool automaticallyImplyLeading;
const CustomAppBar({
Key? key,
this.leading,
this.title,
this.centerTitle,
this.automaticallyImplyLeading = true,
}) : super(key: key);
#override
Widget build(BuildContext context) {
/// This part is copied from AppBar class
final ScaffoldState? scaffold = Scaffold.maybeOf(context);
final bool hasDrawer = scaffold?.hasDrawer ?? false;
final ModalRoute<dynamic>? parentRoute = ModalRoute.of(context);
final bool canPop = parentRoute?.canPop ?? false;
Widget? leadingIcon = leading;
if (leadingIcon == null && automaticallyImplyLeading) {
if (hasDrawer) {
leadingIcon = IconButton(
icon: const Icon(Icons.mood_sharp, color: Colors.yellowAccent),
onPressed: () => Scaffold.of(context).openDrawer(),
);
} else {
if (canPop) {
leadingIcon = IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(
Icons.sentiment_dissatisfied_sharp,
color: Colors.red,
),
);
}
}
}
return AppBar(
leading: leadingIcon,
title: title,
centerTitle: centerTitle,
);
}
#override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}
I am totally flutter beginner.
What I want to do is pass the data (by TextController) from StatefulWidget to another one.
Here is my code (passive Widget)
import 'package:flutter/material.dart';
class VocabularyText extends StatefulWidget {
final String text;
// ignore: sort_constructors_first
const VocabularyText ({ Key key, this.text }): super(key: key);
#override
_VocabularyTextState createState() => _VocabularyTextState();
}
class _VocabularyTextState extends State<VocabularyText> {
Offset offset = Offset.zero;
#override
Widget build(BuildContext context) {
return Container(
child: Positioned(
left: offset.dx,
top: offset.dy,
child: GestureDetector(
onPanUpdate: (details) {
setState(() {
offset = Offset(
offset.dx + details.delta.dx, offset.dy + details.delta.dy);
});
},
child: const SizedBox(
width: 300,
height: 300,
child: Padding(
padding: EdgeInsets.all(8),
child: Center(
child: Text(
'a',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 28,
color: Colors.red
)
),
),
),
)),
),
);
}
}
The thing is here
child: Text(
//
widget.text,
//
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 28,
color: Colors.red
)
),
According to my research, this should work, but it doesn't. Why did I make a mistake?
Here is references
How to add a draggable "textfield" to add text over images in flutter?
Passing Data to a Stateful Widget
Thank you in advance.
edit
i answered before seeing the image it wasn't there
after seeing the image
what causing the problem is this
widget.text
the correct way to use it in Text widget is like this
Text('${widget.text}'),
i would suggest that you do the following
to send data to Statefull Widget first you use Navigator or any other method to open this widget to the user like so
return GestureDetector(
onTap: () => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) =>
//note here between the () you pass the variable
Categories(companies[index].id, companies[index].name)),
)},
and then to receive them you do like this in my case its Categories Class
class Categories extends StatefulWidget {
//getting company id from home page
final int companyId;
final companyName;
Categories(this.companyId , this.companyName);
#override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories> {
#override
Widget build(BuildContext context) {
...... rest of the code
and now to use the data you can do like this for example
widget.companyId
this was an example from my code now lets jump to your code
to receive the text from the text editing controller you do
class TextReceiver extends StatefulWidget {
//getting company id from home page
final String userInput;
TextReceiver(this.userInput);
#override
TextReceiver createState() => _TextReceiver();
}
//to use it
widget.userInput
now to send it you send it through Material Navigator
onTap: () => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => TextReceiver(TextEditingController.text)),
)},
note that you should pass it as TextEditingController.text because the constructor in TextReceiver is specifying the type to String if you passed TextEditingController then the type wouldn't be String it will be TextEditingController type
all of this code is for example and it would't be like your code but it will give you the idea
refer to official docs https://flutter.dev/docs/cookbook/navigation/passing-data
Edit : remove const from this line
child: const SizedBox(
rest of the code
)
to this
child: SizedBox(
rest of the code
)
Like Google Drive, can I create custom menu in Flutter Web application?.
Below the instruction how to implement working context menu called via mouse right button in flutter web app:
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:universal_html/html.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
// Prevent default event handler
document.onContextMenu.listen((event) => event.preventDefault());
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Center(
child: Listener(
child: Icon(
Icons.ac_unit,
size: 48.0,
),
onPointerDown: _onPointerDown,
),
),
);
}
/// Callback when mouse clicked on `Listener` wrapped widget.
Future<void> _onPointerDown(PointerDownEvent event) async {
// Check if right mouse button clicked
if (event.kind == PointerDeviceKind.mouse &&
event.buttons == kSecondaryMouseButton) {
final overlay =
Overlay.of(context).context.findRenderObject() as RenderBox;
final menuItem = await showMenu<int>(
context: context,
items: [
PopupMenuItem(child: Text('Copy'), value: 1),
PopupMenuItem(child: Text('Cut'), value: 2),
],
position: RelativeRect.fromSize(
event.position & Size(48.0, 48.0), overlay.size));
// Check if menu item clicked
switch (menuItem) {
case 1:
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Copy clicked'),
behavior: SnackBarBehavior.floating,
));
break;
case 2:
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Cut clicked'),
behavior: SnackBarBehavior.floating));
break;
default:
}
}
}
}
The only thing is to do is correct positioning of left top corner of context menu.
Until the open issue is resolved, you can do the following in your main():
import 'dart:html';
void main() {
window.document.onContextMenu.listen((evt) => evt.preventDefault());
// ...
}
Here is the open issue for it: https://github.com/flutter/flutter/issues/31955
You can disable it for a webpage like this:
How do I disable right click on my web page?
You can also listen for Pointer Signal events and render the popup in Flutter:
https://medium.com/#crizantlai/flutter-handling-mouse-events-241108731537
Basically on web for example you would disable the default context menu, and show an Overlay in flutter when you receive the right click pointer signal.
Prevent default contextmenu
Add an oncontextmenu attribute to <html> tag in web/index.html:
<!DOCTYPE html>
<html oncontextmenu="event.preventDefault();">
<head>
...
See also: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes#event_handler_attributes
This has the same effect as https://stackoverflow.com/a/64779321/16613821 (window.document is just the <html> tag), but without triggering "Avoid using web-only libraries outside Flutter web plugin packages." warning or using universal_html package.
NOTE: Hot reload won't work for this kind of change, but you can simply refresh(F5) browser.
Add your custom contextmenu
https://github.com/flutter/flutter/pull/74286 doesn't work well for your usecase
This should show up by default on desktop, but only when right clicking on EditableText-based widgets. Right clicking elsewhere does nothing, for now.
This is also purposely not customizable or reusable for now. It was a temporary solution that we plan to expand on.
In general, you can use GestureDetector.onSecondaryTap to detect user's right click.
Thanks for the inspiration BambinoUA. I decided to make my own cross platform class for this.
Works on iOS/Android/Web/Windows/Mac & Linux. Tested.
import 'package:bap/components/splash_effect.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:universal_html/html.dart' as html;
class CrossPlatformClick extends StatefulWidget {
final Widget child;
/**
* Normal touch, tap, right click for platforms.
*/
final Function()? onNormalTap;
/**
* A list of menu items for right click or long press.
*/
final List<PopupMenuEntry<String>>? menuItems;
final Function(String? itemValue)? onMenuItemTapped;
const CrossPlatformClick({Key? key, required this.child, this.menuItems, this.onNormalTap, this.onMenuItemTapped}) : super(key: key);
#override
State<CrossPlatformClick> createState() => _CrossPlatformClickState();
}
class _CrossPlatformClickState extends State<CrossPlatformClick> {
/**
* We record this so that we can use long-press and location.
*/
PointerDownEvent? _lastEvent;
#override
Widget build(BuildContext context) {
final listener = Listener(
child: widget.child,
onPointerDown: (event) => _onPointerDown(context, event),
);
return SplashEffect(
isDisabled: widget.onNormalTap == null,
borderRadius: BorderRadius.zero,
onTap: widget.onNormalTap!,
child: listener,
onLongPress: () {
if (_lastEvent != null) {
_openMenu(context, _lastEvent!);
return;
}
if (kDebugMode) {
print("Last event was null, cannot open menu");
}
},
);
}
#override
void initState() {
super.initState();
html.document.onContextMenu.listen((event) => event.preventDefault());
}
/// Callback when mouse clicked on `Listener` wrapped widget.
Future<void> _onPointerDown(BuildContext context, PointerDownEvent event) async {
_lastEvent = event;
if (widget.menuItems == null) {
return;
}
// Check if right mouse button clicked
if (event.kind == PointerDeviceKind.mouse && event.buttons == kSecondaryMouseButton) {
return await _openMenu(context, event);
}
}
_openMenu(BuildContext context, PointerDownEvent event) async {
final overlay = Overlay.of(context)!.context.findRenderObject() as RenderBox;
final menuItem = await showMenu<String>(
context: context,
items: widget.menuItems ?? [],
position: RelativeRect.fromSize(event.position & Size(48.0, 48.0), overlay.size),
);
widget.onMenuItemTapped!(menuItem);
}
}
The class for standard splash effect touches
import 'package:flutter/material.dart';
class SplashEffect extends StatelessWidget {
final Widget child;
final Function() onTap;
final Function()? onLongPress;
final BorderRadius? borderRadius;
final bool isDisabled;
const SplashEffect({
Key? key,
required this.child,
required this.onTap,
this.isDisabled = false,
this.onLongPress,
this.borderRadius = const BorderRadius.all(Radius.circular(6)),
}) : super(key: key);
#override
Widget build(BuildContext context) {
if (isDisabled) {
return child;
}
return Material(
type: MaterialType.transparency,
child: InkWell(
borderRadius: borderRadius,
child: child,
onTap: onTap,
onLongPress: onLongPress,
),
);
}
}
And how to use it:
return CrossPlatformClick(
onNormalTap: onTapped,
menuItems: [
PopupMenuItem(child: Text('Copy Name', style: TextStyle(fontSize: 16)), value: "copied"),
],
onMenuItemTapped: (item) {
print("item tapped: " + (item ?? "-no-item"));
},
child:
EDIT (2nd):
I made a change the state from Stateful widgets to Stateless widget, and it turns out, I can solve the problem.
EDIT:
So I made a mistake, I shouldn't be making a widget inside onTap function, Instead, I should've instantiate CardMatcher somewhere and then access CardMatcher, send the button's keyword, and let CardMatcher check the keyword for me when the button is clicked.
Any Idea how to do that? Can someone make a simple code for me?
In other words, I want to make a widget that can check if there are two buttons that have been clicked. That widget, should be in another file so it may be reused.
ーーーー
So I made a custom button that will pass a keyword to another widget (CardMatcher) that will check the keyword. If two buttons have the same keywords, then the widget (CardMatcher) will do something about it.
The button will pass the keyword when it is clicked. Sadly, nothing happens. There's no error detected, but the app didn't build the CardMatcher as well. Here's the code for the button:
import 'package:flutter/material.dart';
import 'package:fluttermatchcard/cardMatcher.dart';
import 'package:fluttermatchcard/cardMatcher.dart';
import 'package:fluttermatchcard/testerState.dart';
class CardButton extends StatefulWidget {
final Widget child;
//final GestureTapCallback onPressed;
final double widthBut;
final double heightBut;
final Color colorInitial;
final Color colorClicked ;
final Color textColorInitial ;
final Color textColorClicked ;
final Alignment alignment;
final Text text;
final String keyword;
CardButton({
//#required this.onPressed,
this.child,
#required this.keyword,
this.heightBut =40,
this.widthBut = 75,
this.colorClicked = Colors.white,
this.colorInitial=Colors.amber,
this.textColorClicked = Colors.amber,
this.textColorInitial = Colors.white,
this.alignment = Alignment.center,
this.text = const Text(
"Card",
style: TextStyle(
fontSize: 20,
),
),
});
#override
_CardButtonState createState() => _CardButtonState(
keyword,
widthBut,
heightBut,
colorClicked,
colorInitial,
textColorClicked,
textColorInitial,
alignment,
text,
);
}
class _CardButtonState extends State<CardButton> {
String _keyword;
double _widthBut ;
double _heightBut;
Color _colorInitial;
Color _colorClicked ;
Color _textColorInitial;
Color _textColorClicked ;
Alignment _alignment ;
Text _text;
_CardButtonState(
this._keyword,
this._widthBut,
this._heightBut,
this._colorClicked,
this._colorInitial,
this._textColorClicked,
this._textColorInitial,
this._alignment,
this._text,
);
Color _colorNow;
Color _textColorNow;
bool isClicked = false;
void initState() {
_colorNow=_colorInitial;
_text = Text(_text.data, style: TextStyle(color: _textColorInitial, fontSize: _text.style.fontSize),);
super.initState();
}
void ChangeButton(){
setState(() {
isClicked= !isClicked;
if(isClicked){
_colorNow=_colorClicked;
_text = Text(_text.data, style: TextStyle(color: _textColorClicked, fontSize: _text.style.fontSize),);
}
else{
_colorNow=_colorInitial;
_text = Text(_text.data, style: TextStyle(color: _textColorInitial, fontSize: _text.style.fontSize),);
}
});
//super.initState();//no idea
}
#override
Widget build(BuildContext context) {
return Container(
width: _widthBut,
height: _heightBut,
child: InkWell(
onTap: (){ChangeButton();
CardMatcher(_keyword);
print("onTap");},
child: Container(
padding: EdgeInsets.all(3),
alignment: _alignment,
decoration: BoxDecoration(
color: _colorNow,
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 5,
offset: Offset(0,2),
spreadRadius: 2
)
],
border: Border.all(
color: Colors.amberAccent
)
),
child: _text,
),
),
);
//widget.onPressed();
}
}
for the CardMatcher:
import 'package:flutter/material.dart';
class CardMatcher extends StatefulWidget {
final String keyword_now;
CardMatcher(this.keyword_now);
#override
_CardMatcherState createState() {
print("cardMatch");
_CardMatcherState(keyword_now);
}
}
class _CardMatcherState extends State<CardMatcher> {
String _keyword_1;
String _keyword_2;
String _keyword_now;
_CardMatcherState(
this._keyword_now,
);
void _collectKeywords(){
print("EnterCollect");
setState(() {
if(_keyword_1==null)
{
print("key1");
_keyword_1=_keyword_now;
}
else{
_keyword_2=_keyword_now;
_matchKeyword(_keyword_1,_keyword_2);
}
});
}
void _matchKeyword(_keyWord_one, _keyWord_two){
if(_keyWord_one==_keyWord_two){
//Lock the But
print("MATCH!!!!");
}
}
#override
Widget build(BuildContext context) {
print("BUILD");
_collectKeywords();
return null;
}
}
Save me, please
You try to create the CardMatcher widget in your onTap function!
What you need to do:
1. onTap must just call ChangeButton (but don't create CardMatcher here)
2. ChangeButton must call setState() AND change the _keyword field
3. Use a CardMatcher instance in your build tree with _keyword as constructor parameter
When calling setState, you indicate to flutter to rebuild (i.e. call build()) the widget. If you change a state (i.e. _keyword), then the build method will use the new state's value to build the widget accordling
The only thing that seems to be missing in your code is for you to use the widget. prefix to access the Stateful widgets constructor variables, like this:
class CardMatcher extends StatefulWidget {
final String keyword_now;
CardMatcher(this.keyword_now);
#override
_CardMatcherState createState() {
print("cardMatch");
_CardMatcherState(keyword_now);
}
}
class _CardMatcherState extends State<CardMatcher> {
String _keyword_1;
String _keyword_2;
void _collectKeywords(){
print("EnterCollect");
setState(() {
if(_keyword_1 == null)
{
print("key1");
_keyword_1 = widget.keyword_now;
}
else{
_keyword_2 = widget.keyword_now;
_matchKeyword(_keyword_1,_keyword_2);
}
});
}
void _matchKeyword(_keyWord_one, _keyWord_two){
if(_keyWord_one==_keyWord_two){
//Lock the But
print("MATCH!!!!");
}
}
#override
Widget build(BuildContext context) {
print("BUILD");
_collectKeywords();
return null;
}
}
I want to make a reusable button with a container in GestureDetector which will execute some function if I tap it and its color will become dark if I hold it. Any help, hint, tip would be very much appreciated.
I tried writing the GestureDetector in the custom widget file but it gives me errors.
When i try to extract widget on the GestureDetector it gives an Reference to an enclosing class method cannot be extracted error.
(the main page)
import 'package:flutter/material.dart';
import 'ReusableTwoLineList.dart';
import 'Text_Content.dart';
const mainTextColour = Color(0xFF212121);
const secondaryTextColour = Color(0xFF757575);
const inactiveBackgroundCardColor = Color(0xFFFFFFFF);
const activeBackgroundCardColor = Color(0xFFE5E5E5);
enum CardState {
active,
inactive,
}
class SettingsPage extends StatefulWidget {
#override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
CardState currentCardState = CardState.inactive;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Settings'),
),
body: ListView(
children: <Widget>[
GestureDetector(
onTapDown: (TapDownDetails details) {
setState(() {
currentCardState = CardState.active;
});
},
onTapCancel: () {
setState(() {
currentCardState = CardState.inactive;
});
},
onTap: () {
setState(() {
currentCardState = CardState.inactive;
//some random function
});
},
child: ReusableTwoLineList(
mainTextColor: mainTextColour,
secondaryTextColor: secondaryTextColour,
backgroundCardColor: currentCardState == CardState.active
? activeBackgroundCardColor
: inactiveBackgroundCardColor,
cardChild: TextContent(
mainLabel: 'First Day',
secondaryLabel: 'This is the first day of the week',
),
),
),
ReusableTwoLineList(
mainTextColor: mainTextColour,
secondaryTextColor: secondaryTextColour,
cardChild: TextContent(
mainLabel: '2nd day',
secondaryLabel: 'This is the end day',
),
),
ReusableTwoLineList(
mainTextColor: mainTextColour,
secondaryTextColor: secondaryTextColour,
),
],
),
);
}
}
ReusableTwoLineList.dart (the custom widget i am trying to make)
class ReusableTwoLineList extends StatelessWidget {
ReusableTwoLineList({
#required this.mainTextColor,
#required this.secondaryTextColor,
this.backgroundCardColor,
this.cardChild,
this.onPressed,
});
final Color mainTextColor, secondaryTextColor, backgroundCardColor;
final Widget cardChild;
final Function onPressed;
#override
Widget build(BuildContext context) {
return Container(
color: backgroundCardColor,
padding: EdgeInsets.symmetric(horizontal: 16),
height: 72,
width: double.infinity,
child: cardChild,
);
}
}
This is what i want but in a custom widget so i can use it over and over.
Normal-https://i.imgur.com/lVUkMFK.png
On Pressed-https://i.imgur.com/szuD4ZN.png
You can use extract method instead of extract widget. Flutter will add everything as it is, and instead of a class you will get a reusable function.