i am having this null check error, i am creating a inherited widget of global keys , can anyone pls help me to solve this
class KeysToBeInherited extends InheritedWidget {
const KeysToBeInherited(
{Key? key,
required this.add,
required this.card,
required this.color,
required this.bepy,
required this.me,
required this.publish,
required this.child})
: super(key: key, child: child);
final GlobalKey add;
final GlobalKey card;
final GlobalKey color;
final GlobalKey me;
final GlobalKey bepy;
final GlobalKey publish;
final Widget child;
static KeysToBeInherited of(BuildContext context) {
final KeysToBeInherited? result =
context.dependOnInheritedWidgetOfExactType<KeysToBeInherited>();
return result!;
}
#override
bool updateShouldNotify(covariant KeysToBeInherited oldWidget) {
return true;
}
}
..........................................................................................................................................................................................................................................................................
Check if result is not null and then use result!
Related
I am new in flutter and i have some codes to build textfield. i want to make an initial value in textfield but this is from input in another class.
class TextFieldEdit extends StatefulWidget {
TextFieldEdit({
Key? key,
required this.title,
required this.hintTxt,
required this.controller,
required this.defaultTxt,
}) : super(key: key);
final String title, hintTxt;
final controller;
final defaultTxt;
#override
State<TextFieldEdit> createState() => _TextFieldEditState();
}
class _TextFieldEditState extends State<TextFieldEdit> {
TextEditingController _controller = TextEditingController();
#override
void initState() {
super.initState();
_controller.text = defaultTxt;
}
#override
Widget build(BuildContext context) {
return ...
}
in _TextFieldEditState class at the _controller.text i want to get value from defaultTxt in TextFieldEdit class. But how can i send it to _TextFieldEditState class?
the error message is : Undefined name 'defaultTxt'.
Try correcting the name to one that is defined, or defining the name.
Use widget. to access to the variable in constructor:
#override
void initState() {
super.initState();
_controller.text = widget.defaultTxt;
}
To access the widget variable follow widget.variableName
You can do
late final TextEditingController _controller =
TextEditingController.fromValue(
TextEditingValue(text: widget.defaultTxt));
Or use initState to assign the _controller.
When creating this stateless widget I try to assign a TextDecoration value to a widget attribute based on the value of a boolean attribute from the object being passed to it on creation.
textDecoration = item.isComplete ? TextDecoration.lineThrough : TextDecoration.none,
On this row it marks item.isComplete as an error, saying invalid constant value.
Is it because isComplete in the class is defined with the late keyword and therefore it could be null? I checked all the possible causes for which the invalid constant value error migh arise and I still haven't made any sort of dent into it.
The widget:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import '../models/grocery_item.dart';
class GroceryTile extends StatelessWidget {
final GroceryItem item;
final Function(bool?)? onComplete;
final TextDecoration textDecoration;
const GroceryTile({
Key? key,
required this.item,
this.onComplete,
}) : textDecoration = item.isComplete // Error here
? TextDecoration.lineThrough
: TextDecoration.none,
super(key: key);
#override
Widget build(BuildContext context) {
return Container();
}
}
The class:
import 'package:flutter/painting.dart';
enum Importance { low, medium, high }
class GroceryItem {
final String id;
final String name;
final Importance importance;
final Color color;
final int quantity;
final DateTime date;
late bool isComplete;
GroceryItem({
required this.id,
required this.name,
required this.importance,
required this.color,
required this.quantity,
required this.date,
this.isComplete = false,
});
GroceryItem copyWith({
String? id,
String? name,
Importance? importance,
Color? color,
int? quantity,
DateTime? date,
bool? isComplete,
}) {
return GroceryItem(
id: id ?? this.id,
name: name ?? this.name,
importance: importance ?? this.importance,
color: color ?? this.color,
quantity: quantity ?? this.quantity,
date: date ?? this.date,
isComplete: isComplete ?? this.isComplete);
}
}
The const constructor cannot have a body and if you want to initialize some value in the constructor body you need to remove the const keyword
//...
GroceryTile({ // <- Remove `const`here
Key? key,
required this.item,
this.onComplete,
}) : textDecoration = item.isComplete
? TextDecoration.lineThrough
: TextDecoration.none,
super(key: key);
//...
Try this:
class GroceryTile extends StatelessWidget {
final GroceryItem item;
final Function(bool?)? onComplete;
final TextDecoration textDecoration;
GroceryTile({
Key? key,
required this.item,
this.onComplete,
}) : textDecoration = item.isComplete
? TextDecoration.lineThrough
: TextDecoration.none,
super(key: key);
#override
Widget build(BuildContext context) {
return Container();
}
}
It's the first time a use Flutter (2.8.1) and I'having problems trying to undestrand what's going wrong.
I have a Stateful widget like this:
class SimpleWidget extends StatefulWidget {
final Type2 aValue;
const SimpleWidget({Key key, #required this.aValue}) : super(key: key);
#override
_SimpleWidgetState createState() => _SimpleWidgetState();
}
class _SimpleWidgetState extends State<SimpleWidget> {
Type1 color;
#override
void initState() {
super.initState();
color = widget.aValue; // <-- widget is null
}
...
}
that I call in this way:
List<Type1> something = await showDialog(
context: context,
builder: (context) {
print('currentElement.aValue: ${currentElement.aValue}'); // not null
return SimpleWidget(aValue: currentElement.aValue);
},
);
Why is widget.aValue == null in initState()? How can I solve it?
There are some error in your coding;
The first one is construction of SimpleWidget
const SimpleWidget({Key key, #required this.aValue}) : super(key: key);
when you call like SimpleWidget(aValue: currentElement.aValue); It will should error like key can not be null. You can use ? to make it nullable. Also, # should be remove, it is a syntax error
The correct one looks like
const SimpleWidget({Key? key, required this.aValue}) : super(key: key);
The second one is in SimpleWidgetState
You can change Type1 color; to late Type1 color;
Or make it nullable.
For more details, you can check flutter codelabs
import 'package:flutter/material.dart';
class ThemeSwitcher extends InheritedWidget {
final _ThemeSwitcherWidgetState data; // We'll use ThemeSwitcher to get access to the current state of ThemeSwitcherWidget
const ThemeSwitcher({
Key key,
#required this.data,
#required Widget child,
}) : assert(child != null),
super(key: key, child: child);
static _ThemeSwitcherWidgetState of(BuildContext context) { //This method returns the current state of the ThemeSwitcherWidget. This will be used down the tree
return (context.dependOnInheritedWidgetOfExactType(ThemeSwitcher)
as ThemeSwitcher)
.data;
}
#override
bool updateShouldNotify(ThemeSwitcher old) {
return this != old;
}
}
class ThemeSwitcherWidget extends StatefulWidget {
final bool initialDarkModeOn; // this is the initial state of the variable
final Widget child; // child to which this boolean variable should be propagated upon change. This will be our app in this case
ThemeSwitcherWidget({Key key, this.initialDarkModeOn, this.child})
: assert(initialDarkModeOn != null),
assert(child != null),
super(key: key);
#override
_ThemeSwitcherWidgetState createState() => _ThemeSwitcherWidgetState();
}
class _ThemeSwitcherWidgetState extends State<ThemeSwitcherWidget> {
bool isDarkModeOn;
void switchDarkMode() { //method used to toggle dark mode during the runtime of the app
setState(() {
isDarkModeOn = !isDarkModeOn;
});
}
#override
Widget build(BuildContext context) {
isDarkModeOn = isDarkModeOn ?? widget.initialDarkModeOn; // this is the build method which would build the widget tree with the above info
return ThemeSwitcher(
data: this,
child: widget.child,
);
}
}
Too many positional arguments: 0 expected, but 1 found.
Try removing the extra positional arguments, or specifying the name for named arguments.
This is the Error I am continuously facing the issue after trying many methods.
I would like to know how would this problem can be solved as I am not getting any good solution from searches.
Return the following statement in _ThemeSwitcherWidgetState of(BuildContext context) method of your code:
return (context.dependOnInheritedWidgetOfExactType<ThemeSwitcher>()).data;
When I use VSCode snippet Extract Widget, I have the following :
class MyExtractedWidget extends StatelessWidget {
const MyExtractedWidget({
Key key,
#required T someVariable,
}) : _someVariable = someVariable,
super(key: key);
final T _someVariable;
#override
Widget build(BuildContext context){ return Container(); }
}
However, I am used to write constructors the following way :
class MyExtractedWidget extends StatelessWidget {
const MyExtractedWidget({
Key key,
#required this.someVariable, // Directly accessing variable using "this"
}) : super(key: key);
final T someVariable;
#override
Widget build(BuildContext context){ return Container(); }
}
Do you know why snippets' constructors use a temporary variable instead of directly writing in the variable?
Is it related to encapsulation? If yes, I cannot understand why, as an extracted Widget is written in the same file, and that "underscored" variables are accessible in whole file.
EDIT
I tried with another widget and I have a kind of mix :
class Test extends StatelessWidget {
const Test({
Key key,
#required List<SortedExpense> sortedExpenses,
#required this.expensesSink,
}) : _sortedExpenses = sortedExpenses, super(key: key);
final List<SortedExpense> _sortedExpenses;
final StreamSink<List<Expense>> expensesSink;
...
This is based on the privacy of the variables you're extracting.
For example, the following widget:
Text(_count.toString())
will generate:
class MyName extends StatelessWidget {
const MyName({
Key key,
#required int count,
}) : _count = count, super(key: key);
final int _count;
#override
Widget build(BuildContext context) {
return Text(_count.toString());
}
}
while this widget:
Text(count.toString())
will create:
class MyName extends StatelessWidget {
const MyName({
Key key,
#required this.count,
}) : super(key: key);
final int count;
#override
Widget build(BuildContext context) {
return Text(count.toString());
}
}