Button that creates a new folder in note app - flutter

How can I achieve this?
I want to make folders within folders.
I have this from another question:
class Folder {
final String name;
List<Folder>? folders;
Folder(this.name);
}
class Note {
List<Folder>? folders;
}
class FolderViewer extends StatelessWidget {
final Folder folder;
const FolderViewer({Key? key, required this.folder}) : super(key: key);
#override
Widget build(BuildContext context) {
return Text(folder.name);
}
}
But I don't know how work with that... can you add more to that or give me a different way of achieving this?

Using:
class Folder {
final String name;
List<Folder>? folders;
Folder(this.name);
}
You can easily achieve nested folders like this:
newFolder = Folder("New Folder")
subFolder = Folder("Sub Folder")
newFolder.folders.add(subFolder)
And you can keep on doing it.

Related

Why does flutter call its CLASSES as WIDGETS? Why not call it a class? why the term "widget" is used?

Widget is a class! But why not call it just class and not widget?
I know that every thing in the flutter is a widget and every class is a widget.
Why though?
Maybe call every class gadget or anything else?
I was wondering if my interviewer might ask me this question!
A widget is a class that has the build method:
#override
Widget build(BuildContext context) {
return Container(...);
}
A normal class doesn't have a build method.
You also can make a widget:
create a class that extends StatelessWidget or StatefulWidget
create a widget tree inside the build method:
#override
Widget build(BuildContext context) {
return Container(...); //Widget tree
}
(optional) create a constructor that gives you all the information you need:
var name;
var age;
var location;
//constructor
ClassName({this.name, this.age, this.location});
in the constructor you also can make things required:
var name;
var age;
var location;
//constructor
ClassName({#required this.name, this.age, this.location});
you put the constructor at the beginning of your class:
class WidgetName extends StatelessWidget {
//constructor
WidgetName({
#required this.name,
this.age,
this.location,
});
var name;
var age;
var location;
#override
Widget build(BuildContext context) {
return Container(...); //Widget tree
}
}
or extending StatefulWidget:
class WidgetName extends StatefulWidget {
var name;
var age;
var location;
//constructor
WidgetName({this.name, this.age, this.location});
#override
_WidgetNameState createState() => _WidgetNameState();
}
class _WidgetNameState extends State<WidgetName> {
//inside of this class you can get the data from the constructor like this: widget.name
#override
Widget build(BuildContext context) {
return Container(...);
}
}
and you can use the widget like a normal widget:
WidgetName(
name: "David",
age: 28,
location: "Sofia, Bulgaria",
),
I hope this answer helps you to understand the difference between a normal class and a widget!
Simply, a widget is any class that inherits from the Widget class, typically starting from StatefulWidget or StatelessWidget. A widget is expected to have a certain protocol... in particular, be part of the context tree and also be able to be moved in that tree. Most widgets contribute some view on the UI, but some don't, and are merely for settings like TextTheme.
every flutter class is a Widgdet not right !
every flutter class (Widget build) is a Widgdet is right .
class will never be a widget !
Widget it's more high level construction than class.
Class it's foundation.

How to get an access to a property of an inheriting class

I have one main class and three classes that inherits from it.
class Product {
const Product(this.price);
final int price;
}
class Book extends Product {
const Book(this.genre, super.price);
final String genre;
}
class CD extends Product {
const CD(this.genre, super.price);
final String genre;
}
class Sticker extends Product {
const Sticker(this.color, super.price);
final Color color;
}
And then I have widget that needs either Book or CD. Both have genre property. But I don't have access to it because the main class has only price property.
class BookOrCD extends StatelessWidget {
const BookOrCD(this.product,{Key? key}) : super(key: key);
final Product product;
#override
Widget build(BuildContext context) => Text(product.genre);
}
I can't add genre to Product class because Sticker doesn't need it. And I can't specify if Product is Book or CD because it can be either of them. I know there are lots of workarounds to that problem, but I'm looking for some clean solution. Maybe some generic function as helper for example.
You can check if the current instance is of a specific type like so:
if (product is Book) {
product.genre
}
If you want to include the logic inside your widgets you can do like this for example:
Text((product is Book) ? product.genre : '')

Is it possible to have both a stateful widgets and a stateless widget as subtypes of another class?

I recently tried to create an abstract widget, that has then both a stateless and a stateful implementation, which both can be accessed via factory-methods.
Below I added a minimal example of the only real working solution I have figured out that works for my use case, but it leaves me with some things to be desired.
For example with this solution, I have to declare and override every variable in the sub-classes, while I would really like to rely on the fact that they are subtypes and implicitly have those variables.
Has anyone of you ever needed to do a similar thing? Have you worked out a different approach?
For those concerned about as to why I would need this: I wanted to make a singular Button-Class for my App, that then has different implementations for specific styles of buttons (regular button, a 'striped' button, a button that 'loads' as the user scrolls down a page and becomes active once the user reached the end of the page, etc.). That way I could then simply call 'Button.implementation' wherever i needed a specific button, and have all the button-related Code in the same place.
Cheers.
abstract class A {
final int intellect;
A(this.intellect);
factory A.giveMeB(int intellect) {
return _B(intellect);
}
factory A.giveMeC(int intellect) {
return _C(intellect);
}
}
class _B extends StatelessWidget implements A {
#override
final int intellect;
_B(this.intellect);
#override
Widget build(BuildContext context) {
return SizedBox.shrink();
}
}
class _C extends StatefulWidget implements A {
#override
final int intellect;
const _C(this.intellect, {Key key}) : super(key: key);
#override
_CState createState() => _CState();
}
class _CState extends State<_C> {
#override
Widget build(BuildContext context) {
return Container();
}
}

Using a provider in a custom class flutter

I am creating a program that needs to use Provider to get values. I call my provider like below in a stateful widget
final user = Provider.of<Users>(context);
Now I would like to use the provider in a custom class
class UserInformation {
final user = Provider.of<Users>(context):
}
This won't work because context is not defined. kindly assist on how I can do this without using a BuildContext.
This is my class Users that I have on a separate dart file and use as a model for for my data streams.
class Users {
final String uid;
final String name;
final String department;
final String position;
Users({ this.uid, this.department, this.name, this.position });
}
This is the query I use to pull data from firestore
Stream<List<FormQuestions>> get userData{
return userCollection.where('name', isEqualTo: 'First Name').where('department', isEqualTo: 'department').snapshots()
.map(_userDataFromSnapshot);
}
I would like the name to be a variable that I get from say (user.name) from the model class. and the same for the department.
Thanks.
You can only access classes which are ChangeNotifiers in the descendant widgets in the tree below this provided ChangeNotifier because behind the scenes the Provider uses InheritedWidget (which uses context) to provide you with the ChangeNotifier you put up in the tree
So in your case there is no way to access the Users from UserInformation and you have to alter your code to make a workaround
Edit: this is a suggestion to achieve what you want if you are using this code inside a widget:
class UserInformation{
final User user;
UserInformation(this.user);
}
class SomeWidget extends StatefulWidget {
#override
_SomeWidgetState createState() => _SomeWidgetState();
}
class _SomeWidgetState extends State<SomeWidget> {
void someMethod(){
final User user = Provider.of<Users>(context);
UserInformation userInformation = UserInformation(user);
//do something
}
#override
Widget build(BuildContext context) {
return Container();
}
}
¡Hey! In the class you need to add "with ChangeNotifier":
class Users with ChangeNotifier {
final String uid;
final String name;
final String department;
final String position;
Users({ this.uid, this.department, this.name, this.position });
}
Hope help. Sorry for the english, yo hablo español. :D

Why does Visual Studio Code randomly lose Flutter class imports?

Visual Studio Code randomly gives an error that a class is missing in my code. The class is first imported successfully from the class file into the code. But when I close the file importing it and reopen it, it loses the reference of that imported file and says that the referenced class file could not be found, although it found it before.
I'm creating a widget PersonalActionPlanBox that needs to import the widget PersonalActionPlanRowPreviewBox from file PersonalActionPlanRowPreviewBox.dart. I have already tried to find an answer by Googling and here on Stackoverflow but did not find a clear solution. I have tried importing the widget with both formats like package:... and the relative ../…. But none work.
The widget importing the PersonalActionPlanRowPreviewBox giving the reference error:
import '../PersonalActionPlanRowPreviewBox.dart';
class PersonalActionPlanBox extends StatefulWidget {
final PersonalActionPlan actionPlan;
final UserModel user;
PersonalActionPlanBox({this.actionPlan, this.user});
#override
PersonalActionPlanBoxState createState() => PersonalActionPlanBoxState();
}
class PersonalActionPlanBoxState extends State<PersonalActionPlanBox> {
...
List<Widget> buildRowPreviewBoxes() {
return widget.actionPlan.rows.map((row) {
return new PersonalActionPlanRowPreviewBox (
actionPlanRow: row,
deleteRowCallback: deleteRowEvent,
refreshFollowUpDateCallback: refreshFollowUpDate,
saveActionPlanCallback: saveActionPlan
);
}).toList();
}
...
}
The imported widget PersonalActionPlanRowPreviewBox:
class PersonalActionPlanRowPreviewBox extends StatefulWidget {
final PersonalActionPlanRow actionPlanRow;
final DeleteRowEvent deleteRowCallback;
final RefreshFollowUpDateCallback refreshFollowUpDateCallback;
final SaveActionPlanCallback saveActionPlanCallback;
PersonalActionPlanRowPreviewBox({this.actionPlanRow, this.deleteRowCallback, this.refreshFollowUpDateCallback, this.saveActionPlanCallback});
#override
PersonalActionPlanRowPreviewBoxState createState() => PersonalActionPlanRowPreviewBoxState();
}
class PersonalActionPlanRowPreviewBoxState extends
State<PersonalActionPlanRowPreviewBox> {
...
}
I expect Visual Studio Code to not randomly lose the import/reference to PersonalActionPlanPreviewBox.dart.