How to have stateless code inside a stateful widget in flutter? [closed] - flutter

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I wanted to add a checkbox in my app, hence I tried converting the parent to a stateless widget, however, this caused all the formatting of the app to be disrupted. Is there a way to add stateless code inside a stateful widget?

According to your question, this might work
class Test1 extends StatefulWidget {
#override
_Test1State createState() => _Test1State();
}
class _Test1State extends State<Test1> {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Test app',
home: new Scaffold(
appBar: new AppBar(
title: new Text("THis is stateful"),
),
body: new Test2(),
),
);
}
}
class Test2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("This is stateless"),
),
);
}
}

Maybe use the parent widget as statefull and make a new stateless widget for your checkbox and form and use it inside your statefull widget by importing it.

Related

can you navigate between widgets with only one scaffold

I have created a widget with a scaffold and called a widget in it as
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Everything Store"),
),
body: Register(),
);
}
}
the Register component doesn't have a scaffold in it, but when I try to navigate from the Register widget to another one that also doesn't have a scaffold too, so I used
onPressed: () => {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => login_page()))
},
I got an error as " No Material widget found. "
So is there a way to have one scaffold or should I make a scaffold for each widget?
The scaffold is one of the main widgets that helps you build up the UI screen on a device but a screen doesn't necessarily need it. The error that you are getting it might be because you are not passing the Widget class correctly.
Try to replace login_page() with the class name like so Register().

I have confusion about Dart code in Flutter Framework

import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Text('This is my default text'),
),
);
}
}
I have recently started learning the Flutter framework , and it's hell lot on confusing for me , can u please explain the sections of this code above like , what is that BuildContext
, the MaterialApp (is it a contructor or a class, ? ),
and it's parameters , I tried learning from their docs , but their is just too much its confusing to me , all i know from this code written in this class is that , build method returns a widget , and scaffold is some sort of predefined code which helps with the layout , something like bootstrap helps with CSS
Let's look at it one line at a time.
class MyApp extends StatelessWidget {
In this line you are declaring a class MyApp which extends the Stateless widget class. That means that MyApp will have the functionality of a Stateless widget and the bits of code that you are adding to it.
Widget build(BuildContext context) {
Here you are defining the build method. A Widget needs a build method, that's how flutter knows how to build the widget and show it. The build method receives a BuildContext parameter which is a handle to the location of a widget in the widget tree.
return MaterialApp(
The build method returns a MaterialApp widget. In fact, MaterialApp() is the constructor of the MaterialApp widget.
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Text('This is my default text'),
The constructor of MaterialApp has a home and a body parameter. Here you are passing a Scaffold widget to the Home parameter. The Scaffold widget constructor (Scaffold()) has an appBar parameter, that receives a Widget (in this case, the Widget is AppBar). And the AppBar constructor has a title parameter, which receives a Text widget. And the body parameter also receives a Text widget.
),
);
}
}

Custom widget testing needs Material widget to test

I am trying to perform basic widget testing in Flutter. Basically I would like to have a list with list of data, and display each of the items in a custom widget (BasicListItem) which also has a ListTile widget in it.
Root widget:
class MyApp extends StatelessWidget {
final List taskList = ['List-1', 'List-2', 'List-3'];
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: ListView.builder(
itemCount: taskList.length, itemBuilder: _itemBuilder),
),
);
}
Widget _itemBuilder(BuildContext context, int index) {
final String item = taskList[index];
return BasicListItem(key: Key(item), title: item);
}
}
The list item widget (BasicListItem) takes a title, and use it inside the ListTile widget.
class BasicListItem extends StatelessWidget {
final String title;
const BasicListItem({required Key key, required this.title})
: super(key: key);
#override
Widget build(BuildContext context) {
return ListTile(
leading: Icon(Icons.map),
title: Text(title),
);
}
}
This is the test for it:
testWidgets('has title and Icons', (WidgetTester tester) async {
const testKey = Key('my-key-1');
const testTitle = 'Demo title';
await tester.pumpWidget(BasicListItem(key: testKey, title: testTitle));
expect(find.text(testTitle), findsOneWidget);
});
But the test throws an error:
No Material widget found. ListTile widgets require a Material widget
ancestor.
...
...
The following TestFailure object was thrown running a test:
Expected: exactly one matching node in the widget tree Actual:
_TextFinder:<zero widgets with text "Demo title" (ignoring offstage widgets)>
However, the test does pass if I wrap ListTile around a MaterialApp, inside the BasicListItem build method. Like so:
#override
Widget build(BuildContext context) {
return MaterialApp(
title: title,
home: Scaffold(
body: ListTile(
leading: Icon(Icons.map),
title: Text(title),
),
)
);
}
But doing this I cannot use it inside the ListView widget. And also I would like to have modular/separate custom widgets so that I can use it on different places as well. I am new and maybe I am missing something. How can I build custom widget and test it out? Could you help me out please.
I didn't understand Darshan's answer at first, because I think the code he provided made me implement the MaterialApp and Material widget into BasicListItem widget class build method directly, instead of implementing it on just the test suit. But that gave me the clue to implement it.
So, this is the final test case. I did wrapped MaterialApp and Material widget with BasicListItem, but not in the build method, instead I wrapped them just on the test case:
testWidgets('has title and Icons', (WidgetTester tester) async {
const testKey = Key('my-key-1');
const testTitle = 'Demo title';
await await tester.pumpWidget(MaterialApp(
home: Material(
child: BasicListItem(key: testKey, title: testTitle),
),
));;
expect(find.text(testTitle), findsOneWidget);
});
I hope this will help others like me as well.
The ListTile component comes from the Material part of Flutter UI components & is not an independent widget, therefore it needs a MaterialApp as parent.
You can check that the ListTile is under material library here: https://api.flutter.dev/flutter/material/ListTile-class.html
Also, you can create as many custom Widgets to use in separate modules,
the only requirement would be to use MaterialApp at the very beginning of the app initialisation.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
/// Only this needs to be a MaterialApp
return MaterialApp(
title: 'Welcome to Flutter',
/// this point to different screen widget also, like MainScreen()
/// Or you can start using Scaffold from here as well.
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text('Hello World'),
),
),
);
}
}
It is not necessary to use MaterialApp as a parent on every custom widget you build. Just the root can be fine too.
But if you are using a single widget to simply test out, & it requires a Material ancestor, you can simply wrap the widget in a Material widget as well.
Okay, this is not specifically in Flutter Docs but is hinted about all over the place. On flutter test side we are pumping a root widget to render a frame as our palette used to test widgets.
Translates to you need to create a Root App Widget to wrap the widget under test. eBay's Golden Toolkit supplies the hooks to make this possible via pumpWidgetBuilder which is an extension of Widget Tester.
For more see my blog, https://fredgrott.medium.com

How to fill the space between two text elements with dots in Flutter [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to show data like this:
Burger..........................$9.99
Steak and Potato...............$14.99
Mac and Cheese..................$6.99
How can I implement it in Flutter?
as an option
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) => MaterialApp(home: Home());
}
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Row(
children: [
Text('Burger'),
Expanded(child: Text('.' * 100, maxLines: 1)),
Text('\$9.99'),
],
),
);
}
}
I personally use fDottedLine package https://pub.dev/packages/fdottedline to draw a dotted line in any form.
: Row(
children: [
Text('Burger'),
FDottedLine(
color: Colors.black,
width: 160.0,
strokeWidth: 2.0,
dottedLength: 10.0,
space: 2.0,
),
Text('\$9.99'),
],
),
You have to give the dynamic widgth using MediaQuery

AppBar not showing in scaffold

I've being studying Flutter for about 4 days, it's becoming tedius, now I want put something together. I want to show a different AppBar content at each screen. But it seems my Scaffold's AppBar is begin ignored.
Here's my code:
class Login extends StatelessWidget{
Widget build(BuildContext context){
return Scaffold(appBar: AppBar(title:Text( 'Identification') ), body: Stack( children: [RaisedButton( child: Text("logar"), onPressed: () => {
Navigator.pushNamed(context, '/other-screen')
})]));
}
}
The app bar above it seems invisible, doesn't show
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'title placedholder',
initialRoute: '/',
routes: {
'/' : (BuildContext context) => Login(),
'/other-screen' : (BuildContext context) => Scaffold(body: Row(children: <Widget>[],))
},
I have copied your code into DartPad and the first AppBar seems to be Ok.
The problem is with your second page.
Every time you create a new Scaffold, you need to add an AppBar to it.
Try running flutter clean and then running it again.
I find this fixes most issues when the code is correct but the application doesn't reflect the intended behaviour.