missing concrete implementation of state.build - flutter

I am getting this error in Dart:
"Missing concrete implementation of "state.build""
The first method is the following:
class MyHomePage extends StatefulWidget {
// String titleInput;
// String amountInput;
#override
MyHomePageState createState() => MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
final List<Transaction> _userTransactions = [
// Transaction(
// id: "t1",
// title: "New Shoes",
// amount: 69.99,
// date: DateTime.now(),
// ),
// Transaction(
// id: "t2",
// title: "Weekly Groceries",
// amount: 16.53,
// date: DateTime.now(),
// ),
];
Does anyone knows what this error means and how to solve it?
Thank you.

You need to add a build method to the State of your widget, this method describes the part of the user interface represented by your widget, e.g.,
(add this to the MyHomePageState)
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:
Container(
height: 200,
width: 100,
color: Colors.yellow,
),
),
);
}

Check the curly brace that closes the class where the Widget build method is found. You might just have closed it in the wrong place.
This was the case for me.
So make sure your build method is within the curly braces that enclose the class
class _LandingPageState extends State<LandingPage> {
Widget build(BuildContext context) {
...
}

All the Stateful widgets and Stateless widgets should have build method.
#override
Widget build(BuildContext context) {
return Container(
...
);
}
If you want to use it without build do not extend the class with State, use it like
class YourClassName {
}

Goto the definitation of State<T> class and see what are the abstract methods. You will find build() method as the only abstract method i.e. a method without body. So when yu are inheriting from State<MyHomePage>, you must override the build() and give a body; basically you will create your Widgets inside the build() method.
So to fix the error add the below code to your class:
class MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold( // Your Widget
...
);
}
}

Just check
#override
Widget build( Buildcontext context)
{
return Container();
}
Check spelling of build
reason : As u extend your class with stateless or statefull widget , U use overiding method to over ride the pre defined method which is already written in parent class which is
state less/full class

Related

flutter slider not updating widget variables

am playing around with the slider widget on flutter, and I can't figure out why it does not update certain values in a different widget, example code is shown below;
When i move the slider, it has no issues moving, but the value i'm trying to update on the other widget does not update even though the onchanged is updating the variable passed through in a set state accordingly.
any help would be greatly appreciated!
Scaffold Code
class TestPage extends StatelessWidget {
static const id = "test_page";
#override
Widget build(BuildContext context) {
double testValue = 0;
return Scaffold(
body: Column(
children: [
Text("Hello World"),
TestBoxNumber(
numberDisplay: testValue,
),
TestSlider(testValue: testValue),
],
),
);
}
}
Slider Code
class TestSlider extends StatefulWidget {
double testValue;
TestSlider({required this.testValue});
#override
_TestSliderState createState() => _TestSliderState();
}
class _TestSliderState extends State<TestSlider> {
#override
Widget build(BuildContext context) {
return Slider(
activeColor: themeData.primaryColorLight,
value: widget.testValue,
min: 0,
max: 100,
divisions: 100,
label: widget.testValue.round().toString(),
onChanged: (double value) {
setState(() {
widget.testValue = value;
});
},
);
}
}
Different Widget Code
class TestBoxNumber extends StatefulWidget {
final double numberDisplay;
const TestBoxNumber({required this.numberDisplay});
#override
_TestBoxNumberState createState() => _TestBoxNumberState();
}
class _TestBoxNumberState extends State<TestBoxNumber> {
#override
Widget build(BuildContext context) {
return Container(
child: Text(widget.numberDisplay.toString()),
);
}
}
The problem is that you are constructing TestBoxNumber widget in such a way that value (testValue) will always be the same (testValue is never returned out of the TestSlider widget).
How to overcome this issue?
You can make your TestPage a StatefullWidget. Then create callback from TestSlider, so when you change value in TestSlider you will call some function in TestPage (with setState in it, causing re-rendering your page).
Or if you don't want your whole TestPage widget to be Statefull (if, let's say, you predict a lot of other static widgets in it and you don't want them to be re-rendered because you just moved a slider), you can create wrapper Statefull widget and put both TestSlider and TestBoxNumber widgets in it. This is more flexible approach, imho.
Here is small scheme of what I mean by wrapping two widgets in another one:
UPD: btw, there is no point in making TestBoxText a statefull widget if it's only purpose is to display a text and you pass it's value through the constructor.

what does it mean when we see people calling widget in dart?

I have seen many times people calling widget. sth inside the code.
May I know what it is actually doing?
For example code below, (highlighted part is my confusion)
class _MyOwnClassState extends State<MyOwnClass> {
#override
Widget build(BuildContext context) {
return ListTile(
title: Container(
child: Column(children: makeWidgetChildren(**widget.jsonObject)**),
),
);
}
}
In flutter's StatefulWidget, we have the following architecture.
You have a StatefulWidget like this,
class MyOwnClass extends StatefulWidget {
State createState () => _MyOwnClassState();
}
And you have a State class for your StatefulWidget like this,
class _MyOwnClassState extends State<MyOwnClass> {
}
Now, State class is meant to house variables that tend to change in order for your UI to be rebuilt.
So you can have variables in your State that you can update using setState.
But what if you had some data that doesn't change and you want to avoid putting them inside the State class.
That's where your StatefulWidget comes to play.
You can store variables in your MyOwnClass and the widget variable inside the State class gives you a way to access them.
For example,
class MyOwnClass extends StatefulWidget {
int numberThatDoesntChange = 1;
State createState () => _MyOwnClassState();
}
You can access them in your State class like this,
class _MyOwnClassState extends State<MyOwnClass> {
Widget build(BuildContext context) {
return Text('$widget.numberThatDoesntChange');
}
}
Apart from this, your StatefulWidget has many more internal instance members that you can access inside of your State class using the widget variable.
The widget refers to the actual view that renders on the screen. It extends the StatefulWidget class of the flutter framework and overrides the createState() method. The createState() method is used to create the instance of state class. We will look into createState().
The state class is used to maintain the state of the widget so that it can be rebuilt again. It extends the State class of the flutter framework and overrides the build method.
The framework calls build() method again and again whenever setState() method is called. The setState() method notifies the framework that the internal state of this object has changed and it should be rebuilt. Suppose we change the value of text in StatefulWidget then we need to call setState().
Edit As Nisanth pointed outh in his comment - I missed your question completely; please ignore the below....
Let me try my answer, I don't think others are getting your point.
In your exapmle, Column(children: x) expect a list of Widgets.
You have two options - either provide this list directly:
class _MyOwnClassState extends State<MyOwnClass> {
#override
Widget build(BuildContext context) {
return ListTile(
title: Container(
child: Column(children: <Widget>[SomeWidget()]),
),
);
}
}
Or if you have more complex code that generates widget - based on input parameters, or you have the same widget generated multiple times and you want to avoid the code duplication - you would create the separate function to do the job.
Something like:
class _MyOwnClassState extends State<MyOwnClass> {
List<Widget> makeWidgetChildren(int param) {
/*
some very complex logic here
/*
if (param>3 && param<4) {
return List<Widget>.generate(4, (index)=>SomeWidget1(index));
} else {
return <Widget>[Center()];
}
}
#override
Widget build(BuildContext context) {
return ListTile(
title: Container(
child: Column(children: makeWidgetChildren(**widget.jsonObject)**),
),
);
}
}
So basically, it is just to make the code nicer; and to avoid having code repeated over and over again in the build function.

Seperate steps in stepper into different files

I try to make each step will be in another dart file. (Steps contains a lot of code, it's hard to maintain it in single file)
What is the idea?
Create Scaffold with stepper (parent widget)
Parent widget creates an instance of steps, each instance modifies the same model (object of class)
Parent widget may call isValid() method on each step. (if it's valid, we can switch to next step)
Requirements:
Steps may be StatefulWidget or StatelessWidget (it may be hard to achieve so StatefulWidget will be enough)
Each step should contain bool isValid() method.
What I have? - Almost nothing
abstract class ValidatedStep {
bool isValid();
}
And see below Step, we implement this abstract class into Step1, but this method should ask state if it's valid. From StatefulWidget we do not have access to state.
class Step1 extends StatefulWidget implements ValidatedStep {
//its ok to create it here?
final _Step1State state = _Step1State();
#override
_Step1State createState() {
//we could (and should?) create state here, but variables in this widget should be final
return state;
}
#override
bool isValid() {
return state.isValid();
}
}
class _Step1State extends State<Step1> implements ValidatedStep {
#override
Widget build(BuildContext context) {
return Container();
}
#override
bool isValid() {
return true;
}
}
You can use map.. Here is a modified example of my code.. Perhaps you can modify to add function to validate the steps.
You can simply put the different Widget from different files in the list.
class StepperScreen extends StatelessWidget {
final List<SomeClass> list;
StepperScreen({#required this.list});
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text(
'Stepper Screen',
),
),
body: Stepper(
steps: getStep(list),
),
),
);
}
}
List<Step> getStep(List<SomeClass> list) {
return list
.map(
(e) => Step(
title: Text(
e.name,
style: TextStyle(fontSize: 20),
),
content: e.child,
),
)
.toList();
}
Of course, your SomeClass should have the properties:
class SomeClass {
String name;
Widget child;
SomeClass({#required this.name, #required this.child});
}
A bit late to the party, but instead of asking the step if it isValid() pass some callback e.g. onReadyChange(bool) down to the step and call it from within the step according to your business logic.

Best way to pass data from a root to deeper child widget in Flutter

I am new to flutter. My flutter widget tree is getting deeper and deeper, I want to know which is the best method to pass data from a root to a widget which is much deeper from it. I'm currently passing it as a constructor from widget to widget.
My current implementation is given below
Level1(data: data)
Level2(data: data)
Level3(data: data)
Level4(data: data)
suppose my data is retrieved from DB in level1 widget and it is used in level4 widget. As we see, my current implementation is considerably messy. How this is generally done? what is the best practice?
You might like to use Provider. You can find more about it here.
Basically, you create provider of the data at the top-most level like:
class Level1 {
#override
Widget build(BuildContext context) {
Provider<Data>(
create: (_) => Something(),
child: Level2 (
// stuff of level 2
),
),
}
}
Something in this case bight be a change notifier.
You can then access it at a lower level with:
final provider = Provider.of<Something>(context);
Inherited widget - If you want to avoid using any third party library..
More can be found here - https://medium.com/#mehmetf_71205/inheriting-widgets-b7ac56dbbeb1
and here https://www.youtube.com/watch?v=Zbm3hjPjQMk
class MyInheritedWidget extends InheritedWidget {
final int accountId;
final int scopeId;
MyInheritedWidget(accountId, scopeId, child): super(child);
#override
bool updateShouldNotify(MyInheritedWidget old) =>
accountId != old.accountId || scopeId != old.scopeId;
}
class MyPage extends StatelessWidget {
final int accountId;
final int scopeId;
MyPage(this.accountId, this.scopeId);
Widget build(BuildContext context) {
return new MyInheritedWidget(
accountId,
scopeId,
const MyWidget(),
);
}
}
class MyWidget extends StatelessWidget {
const MyWidget();
Widget build(BuildContext context) {
// somewhere down the line
const MyOtherWidget();
...
}
}
class MyOtherWidget extends StatelessWidget {
const MyOtherWidget();
Widget build(BuildContext context) {
final myInheritedWidget = MyInheritedWidget.of(context);
print(myInheritedWidget.scopeId);
print(myInheritedWidget.accountId);
...

Flutter - New StatefullWidget, why related createState() method not called?

in the 'TestPageState', I put a button to call 'setState' method. new TestChildWidget() will create a new TestChildWidget,default construtor TestChildWidget() is called, but why 'createState()' method in TestChildWidget not called?
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new TestPage()
);
}
}
class TestPage extends StatefulWidget{
TestPageState createState(){
print('TestPageState createState');
return new TestPageState();
}
}
class TestPageState extends State<TestPage>{
#override
Widget build(BuildContext context) {
print('TestPageState Build');
// TODO: implement build
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TestChildWidget(),
RaisedButton(
child: Text("刷新"),
onPressed: () => setState(() => print('setState')), //build method will called, new TestChildWidget() will be called
)
],
);
}
}
class TestChildWidget extends StatefulWidget{
TestChildWidget(){
//new TestChildWidget(), this default construtor will be called, but why createState() not called?
}
#override
State<StatefulWidget> createState() {
// TODO: implement createState
print('TestChildWidget createState');
return new TestChildWidgetState();
}
}
class TestChildWidgetState extends State<TestChildWidget>{
#override
Widget build(BuildContext context) {
print('TestChildWidgetState build');
// TODO: implement build
return Text('1111');
}
}
in the 'TestPageState', I put a button to call 'setState' method. new TestChildWidget() will create a new TestChildWidget,default construtor TestChildWidget() is called, but why 'createState()' method in TestChildWidget not called?
It creates a state or calls the state build when the state is created.
class TestChildWidgetState extends State<TestChildWidget>{
TestChildWidgetState(){
print("Created only once");
}
}
The framework calls createState whenever it inflates a StatefulWidget, which means that multiple State objects might be associated with the same StatefulWidget if that widget has been inserted into the tree in multiple places. Similarly, if a StatefulWidget is removed from the tree and later inserted in to the tree again, the framework will call createState again to create a fresh State object, simplifying the lifecycle of State objects.
See StatefulWidget
print(...) log maybe not print to console but Flutter have called createState()
You can try use:
developer.debugger(when: true);
in createState()
when setState() called, it will call
abstract class Widget extends DiagnosticableTree {
const Widget({ this.key });
final Key key;
···
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
}
if canUpdate() return true, it means there is no need to create a new element.
The Stateful widget has a default parameter 'Key'. If you supply it with a different value each time - that would enforce new state to be created i.e createState() called.
Instead of new TestChildWidget(), try:
new TestChildWidget(
key: Key('different key for diff states'), // or key: UniqueKey()
),
I actually use the same key value for states that are same, in order to have the caching in those cases.