I have defined enum like:
enum Status {
done,
current,
future
}
I want to include this enum inside the class which is defined below.
Both the enum and class are in same file.
The enum is defined outside of the class because multiple classes should be able to use it.
When using the enum vscode is giving me an error Status not defined
class WeekDay extends StatelessWidget {
final int day;
final Status status;
const WeekDay({this.day, this.status});
#override
Widget build(BuildContext context) {
return Container();
}
}
How do we import Enum in class in Dart?
You need to import the files your are depending on like the following (if e.g. status and weekday are in the same folder):
Sorry, for the silly question.
It Was VSCODE problem,
The error was gone after restarting the vscode.
The above code works perfectly fine.
Related
This is a follow-up question to
How does the const constructor actually work?,
So far from what I've read about const constructors in Dart, it ensures that only one object of the class in question is allocated. In theory, this can save allocation space and execution time. It's even recommended to apply it wherever possible when following Effective Dart design.
Now, say we have a stateless widget Foo:
import 'package:flutter/material.dart';
class Foo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("Hello world");
}
}
Without defining an explicit const constructor, this widget cannot be used in a const context. In other words, the following snippet
import 'package:flutter/material.dart';
class Bar extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const Foo();
}
}
is illegal. But is there even a benefit to adding a const Foo(); to the Foo class if it doesn't (and won't have) any fields in the foreseeable future?
Yes, there is a benefit. You should declare as const if possible.
According to the Flutter doc:
Use const widgets where possible, and provide a const constructor for the widget so that users of the widget can also do so.
The benefits are the same as having a default vs const constructor:
Performance (see)
Your code is consistent and sound
Are used as annotations
Can use in compile switch
You can enable const by default using Lint
I have Android development background and I'm learning Flutter.
In Android it's a common practice to use Kotlin sealed classes to return a state from ViewModel e.g.
sealed class MyState {
data class Success(val data: List<MyObject>) : MyState()
data class Error(val error: String) : MyState()
}
I want to use similar pattern in Flutter and return a State object from the BLOC class. What is the best way to achieve the same in Flutter?
Such use case would be done using named factory constructors.
It requires a lot more code, but the behavior is the same.
class MyState {
MyState._();
factory MyState.success(String foo) = MySuccessState;
factory MyState.error(String foo) = MyErrorState;
}
class MyErrorState extends MyState {
MyErrorState(this.msg): super._();
final String msg;
}
class MySuccessState extends MyState {
MySuccessState(this.value): super._();
final String value;
}
RĂ©mi Rousselet's answer is somehow correct but as sindrenm mentioned:
Unfortunately, this isn't the same thing. Kotlin sealed classes guarantee that there are no other implementations of the given class outside of the file they're defined in. That means you can exhaust when statements (switch in Dart) by just providing all possible alternatives as cases, not having to think about potential sub-classes elsewhere
While there is an active discussion about this feature on dart language: Algebraic Data Types, but there is some libraries that can help you implement this behavior. You can use this libraries:
Sealed Unions
Super Enum
Sealed Class
And if you are using BLoC library you can use this lib:
Sealed Flutter Bloc
I hope that dart language add this feature ASAP
Soon Dart is going to support sealed classes.
GitHub Code: source
sealed class Either {}
class Left extends Either {}
class Right extends Either {}
You can now test the sealed class
test(Either either) {
switch (either) {
case Left(): print('Left');
case Right(): print('Right');
}
}
Here is the package for the Sealed Classes/Unions in Flutter
Freezed
This Package provided the features to deal with Data Classes, Sealed Class in Dart/Flutter
Here is the link which explains the beast use of freezed package in Flutter
Use of Freezed Package in Flutter/Dart
I'm having a terrible time getting this program to run. I keep getting compiler troubles when I run the code. See specifics below. Anybody understand what's going on here?
My code extract from file TapScreenToo.dart:
import 'profiles.dart';
import 'package:flutter/material.dart';
import 'cards.dart';
class PageTapScreen extends StatefulWidget {
final List<Profile> profileList;
Key key;
PageTapScreen({
this.key,
this.profileList,
}) : super(key: key); // constructor
#override
_PageTapScreenState createState() => new _PageTapScreenState();
}
The profile class in file profiles.dart (no import statement there):
class Profile {
final String ttaKey;
final String imageUrl;
final String displayName;
Profile({
this.ttaKey,
this.imageUrl,
this.displayName,
});
}
my profile list from file demoProfiles.dart:
import 'profiles.dart';
final List<Profile> demoProfiles = [
new Profile(
ttaKey: "0",
imageUrl: 'http://localhost:8080/photo_0.jpg',
displayName: 'abc',
),
new Profile(
ttaKey: "1",
imageUrl: 'http:// ... etc
),
]
And all of this gets called in main.dart
import 'package:flutter/material.dart';
import 'tapScreenToo.dart';
import 'demoProfiles.dart';
class _MyHomePageState extends State<MyHomePage> {
final Key keyOne = PageStorageKey('pageOne');
...
#override
void initState() {
tapScreen = PageTapScreen(
key: keyOne,
profileList: demoProfiles, <--- error points here
);
I'm getting a compiler message at the time of initiation:
compiler message: lib/main.dart:68:20: Error: A value of type 'dart.core::List<#lib1::Profile>' can't be assigned to a variable of type 'dart.core::List<#lib2::Profile>'.
compiler message: Try changing the type of the left hand side, or casting the right hand side to 'dart.core::List<#lib2::Profile>'.
compiler message: profileList: demoProfiles,`
I've tried to cast (List <Profile>) but that seems to be a fail, or I'm just doing it wrong.
Note: when I remark out the error line, and debug step to the failure location, I can see that the values for both keyOne and demoProfiles are exactly as expected. Note, these code snippets are located in different files, linked via import commands.
As I look at the rest of the code, I can see where import 'profiles.dart' gets called multiple times.
I don't understand the error message. I've also studied this posting with a similar error, but I'm just not seeing what's going on with this code, nor how to fix it.
You need to change the imports in the main.dart:
import 'tapScreenToo.dart';
import 'demoProfiles.dart';
Since the main.dart can only have packages: imports which are called absolute imports.
Therefore change the imports to:
import package:mypackage/path/tapScreenToo.dart
import package:mypackage/path/demoProfiles.dart
Check this:
Error: A value of type 'List<#lib1::Data>' can't be assigned to a variable of type 'List<#lib2::Data>
https://github.com/dart-lang/sdk/issues/33076
https://www.dartlang.org/tools/pub/get-started#importing-libraries-from-packages
I've created a small app to add items in list, however when i delete something from list, it gets deleted successfully but ListView.builder doesn't show correct values. i know its something related to keys given to class but i'm pretty new in flutter so don't know how to do that.
Gist: https://gist.github.com/OculusMode/213052325ec725aad3ab92c73599b187
Thanks in advance.!
Add this to constructor of your Widget:
:super(key:new ObjectKey(_data))
Example:
class TodoTile extends StatefulWidget {
String _data;
int _index;
ValueChanged<int> onDelete;
TodoTile(this._data,this._index,{ #required this.onDelete , Key key}):super(key:new ObjectKey(_data));
TodoTileState createState() {return new TodoTileState(_data, _index,this.onDelete);}
}
Not sure if this would cause problems too but I've also changed widget.onDelete to onDelete (passing the function pointer to the state too)
Source:
https://flutter.io/widgets-intro/#keys
I'm trying to obtain the top-level state of my app using a .of()-method, similar to the Scaffold.of() function. This is the (stripped down) code:
class IApp extends StatefulWidget {
#override
IAppState createState() => new IAppState();
static IAppState of(BuildContext context) =>
context.ancestorStateOfType(const TypeMatcher<IAppState>());
}
The app is started using runApp(new IApp)
This Widget creates a HomePage:
#override
Widget build(BuildContext context) {
return new MaterialApp(
// ommitted: some localization and theming details
home: new HomePage(),
);
}
Then, I try to access the State from the HomePage (a StatefulWidget itself):
#override
Widget build(BuildContext context) {
return new Scaffold(
// ommited: some Scaffold properties such as AppBar
// runtimeType not actual goal, but just for demonstration purposes
body: new Text(IApp.of(context).runtimeType.toString()),
);
}
The strange this is, the code works when I place the code for HomePage in the same file as the IApp, but just as an extra class. However, when I place HomePage in a separate file (main.dart and homepage.dart importing each other), the return value of IApp.of(context) is null.
What causes this? And how can I fix it?
TDLR: imports file only using
import 'package:myApp/path/myFile.dart';
Never with
import './myFile.dart';
This is due to how dart resolves imports.
You may have a single source file, but during builds, there is some kind of duplicates.
Let's say you're working on 'myApp'. To import a file, you could do both :
import 'relativePath/myFile.dart'
import 'package:myApp/path2/myFile.dart'
You'd think that they point to the same file right?
But no. One of them will point to the original source. While the other one will point to a temporary file used for the build.
The problem comes when you start to mix both solutions. Because for the compiler, these two files are different. Which means that IApp imported from package:myApp/IApp is not equal to the same IApp imported from relativePath/myApp/IApp
In your case, you inserted in your widget tree an IApp from pakage:path but your IApp.of(context) use IAppState resolved locally.
They both have a different runtimeType. Therefore const TypeMatcher<IAppState>() won't match. And your function will return null.
There's an extremely easy way to test this behavior.
Create a test.dart file containing only
class Test {
}
then in your main.dart add the following imports :
import 'package:myApp/test.dart' as Absolute;
import './test.dart' as Relative;
You can finally test this by doing :
new Relative.Test().runtimeType == new Absolute.Test().runtimeType
Spoiler: the result is false
Now you can use the relative path.
You can verify this, as Remy suggested two years ago:
Relative.Test().runtimeType == Absolute.Test().runtimeType
Spoiler: the result is true