Stateless Widgets - Endlich übersichtlicher Code (Flutter Tutorial #8)
HTML-код
- Опубликовано: 22 авг 2024
- Im letzten Video haben wir viel Code geschrieben. In diesem Video schauen wir uns an wie wir Widgets selbst definieren können um unseren Code übersichtlich zu halten.
Link zum Code:
github.com/sim...
Herzlich Willkommen auf dem RUclips Channel von STARTUP TEENS!
Hier findest du die coolsten Erklärvideos zum Thema Unternehmertum in ganz Deutschland!
Natürlich produziert von simpleclub 😎
Wenn dir die Videos gefallen, empfehle uns deinen Freunden und teile unsere Videos!
» WAS IST STARTUP TEENS
STARTUP TEENS ist die erste Online-Plattform Deutschlands, die Jugendlichen unternehmerisches Denken und Handeln beibringt.
Und zwar in drei Schritten:
• EVENTS
• ONLINE TRAINING
• BUSINESS PLAN WETTBEWERB
Bei den Events wirst du von Unternehmern inspiriert, beim Online Training lernst du das Handwerkszeug des Unternehmertums und beim Business Plan Wettbewerb kannst du deine eigene Idee umsetzen und 7x 10.000 Euro gewinnen!
» ERFAHRE MEHR AUF
www.startuptee...
Bitte macht die Videos so, dass man, wenn man durcheinander kommt, auch so, das man zum Schluss den VOLLSTÄNDIGEN Code zu sehen bekommt! Ansonsten echt geile Idee :)!
Unten im Link siehst du immer den vollständigen Code
Lösung für Checkbox-Fehler:
Ok, keine Ahnung, ob das Video mittlerweile veraltet ist und sich in Dart viel getan hat (die Sprache kam erst 2013 raus und da verändert sich noch viel), aber der Code im Video funktioniert so nicht mehr. Ich packe dir gleich den nötigen Code ans Ende dieses Beitrags, den kopierst du dir dann einfach statt des StatelessWidgets hinein, aber ich sollte noch ein bisschen was erklären, denn du willst ja lernen und nicht einfach kopieren.
Checkbox kann nicht mehr in einem Stateless Widget verwendet werden, weil eine Checkbox durch die Möglichkeit, sie anzuhaken, bzw. den Haken zu entfernen, verändert wird. Damit ändert sich auch das Widget und ist nicht mehr stateless, also zustandslos. (Falls jetzt noch ein Fragezeichen da ist: Der wechselnde Zustand ist der gesetzte Haken, der da sein kann, oder eben nicht.)
Das ganze Widget muss also stateful sein, also in seinen Zuständen wechseln können.
Und es gibt auch genau das: Wir extenden also nicht mehr StatelessWidget, sondern StatefulWidget, das allerdings ein bisschen anders aufgebaut ist. Die Details werd ich jetzt nicht erläutern, weil ich hoffe, dass stateful Widgets noch später in der Videoreihe kommen. (Ich hab die selbst noch nicht gesehen und lerne auch erst noch, aber ich hab jetzt einige Zeit recherchiert, damit wir hier weitermachen können und teile das nur mit dir . Kannst dich mit nem Abo auf meinem Kanal bedanken, wenn du Bock hast. Vielleicht lad ich auch irgendwann mal wieder was hoch. :D))
So genug der Rede, hier kommt jetzt der Code und danach noch ne ganz kurze Erklärung zu ein paar Punkten:
class SingleToDo extends StatefulWidget {
const SingleToDo({Key? key, required this.title}) : super(key: key);
final String title;
@override
State createState() => _SingleToDoState();
}
class _SingleToDoState extends State {
bool checked = false;
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 22
),
child:
ListTile(
leading: Checkbox(value: checked, onChanged: (value){
setState(() {
checked = value!;
});
},
),
title: Text(widget.title,
style: const TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w600,
color: Colors.black54),
),
trailing: const Icon(Icons.delete_outline),
),
);
}
}
Erklärungen:
Mal vorweg, es ist nicht ganz so schlimm, wenn du hier nicht alles verstehst, aber ich versuche es so zugänglich wie möglich auszudrücken.
Checkbox erfordert in seinem Konstruktor (Da wo du vorher value: false, eingegeben hast) mittlerweile auch zwingend den Parameter "onChanged:", der eine Funktion erwartet, in der definiert wird, was passiert, wenn der Haken gesetzt, bzw. entfernt wird. Das ist eigentlich ziemlich cool, weil du damit auch festlegen kannst, dass noch andere Dinge passieren, wenn du den Haken setzt.
Wir benutzen also die boolsche (wahr oder falsch) Variable "checked", die ich weiter oben definiert habe und geben sie erst mal an "value:". In "onChecked:" ändern wir sie dann und sorgen mit der Funktion "setState" - die nur in stateful Widgets verwendet werden kann - dafür, dass wir auch sehen, dass der Haken gesetzt wird oder eben entfernt. "setState" lädt, wenn ich Dart bisher richtig verstanden habe, nämlich das Widget neu, bzw. ermöglicht es, das Widget zu ändern.
Ich kann dir leider an diesem Punkt meines Wissens noch nicht erklären, warum da ein Ausrufezeichen hinter "value" in der setState-Methode stehen muss. Das hat irgendwas damit zu tun, dass der Datentyp, den wir da in Klammern hinter "onChanged:" haben, kein richtiger "bool" ist, sondern ein "bool?"... Kein Plan, wo da der Unterschied ist, aber wir akzeptieren das jetzt mal so, denn der Code funktioniert.
Du könntest value übrigens auch anders benennen, nur damit dich das jetzt nicht verwirrt. Also an der Stelle könnte auch stehen:
Checkbox(value: checked, onChanged: (irgendeinName){
setState(() {
checked = irgendeinName!;
});
},
),
Tja, mehr gibt es wohl gerade nicht zu sagen. Schauen wir uns einfach mal weiter die Videoreihe an, mal sehen, was noch kommt. Vielleicht muss ich ja an irgendeiner Stelle noch mal was korrigieren und dann sehen wir uns wieder (oder auf meinem Kanal ;) ), aber ich hoffe, dass ich das nicht tun muss, denn das ist verdammt anstrengend.
Jedenfalls freue ich mich, wenn ich dir helfen und den Frust ersparen konnte.
Wenn noch Fragen offen sind, stell sie ruhig.
Viel Erfolg weiterhin.
Edit:
Evtl. hast du immernoch einen Fehler, der mit diesem Problem aber gar nichts zu tun hat. Schau mal links in den Dateiordner, da ist irgendwo ein Ordner "test" (den kannst du mit dem kleinen ^ Pfeil aufklappen, wenn er zu ist), darin befindet sich eine Datei namens "widget_test.dart". Öffne die mal mit einem Doppelklick und du wirst den Fehler schon sehen: Da ist irgendwo relativ weit oben das Wort MyApp unterstrichen. Wenn du dich an den Anfang der Reihe erinnerst: Da haben wir die Klasse MyApp gelöscht und jetzt wundert sich das Programm halt, wo die Klasse abgeblieben ist. Ändere MyApp einfach zu ToDo, also der Klasse, die wir selbst erstellt haben und alles sollte laufen.
Edit 2:
Wenn du übrigens dein SingleToDo-Widget oben in der ToDo-class einbindest und ihm einen Titel mitgeben willst, musst du das mittlerweile auch ein klein wenig anders machen.
Du schreibst dann hinein, welche Variable du setzen möchtest, denn du kannst an ein Widget so viele Varablen übergeben, wie du willst.
Das sieht beispielsweise so aus:
return Scaffold(
appBar: AppBar(
title: const Text('To-Do-App'),
backgroundColor: const Color.fromRGBO(35, 0, 0, 100),
),
body: Column(
children: const [
SingleToDo(title: 'Tomate'),
SingleToDo(title: 'Abo für Cruentus')
]
)
);
Edit3:
Ok, hab noch mal geschaut, was das mit diesem "bool?" auf sich hat. Das wird jetzt wahrscheinlich absoluten Programmier-Neueinsteigern nichts sagen, aber falls das auf dich zutrifft, kannst du es trotzdem lesen, denn dümmer wirst du dadurch wahrscheinlich nicht. ;)
In Dart gibt es das Konzept der null-safety. Das bedeutet so viel wie, dass es Variablentypen gibt, die nicht "null" sein können. null bedeutet in der Programmierung nicht, dass es den Wert 0 hat, sondern dass es sich um leeren Speicher handelt. (Der Wert 0 ist übrigens nicht leerer Speicher, denn es gibt ja den Wert(!) 0. null bedeutet so viel wie nix, nada, niente. Quasi Vakuum.)
So, in Dart kannst du solchen nicht-nullierbaren (eigene Wortschöpfung) Variablen aber eben doch null zuweisen, indem du Dart mitteilst, dass du das eben gern tun willst. Wie geht das? Mit dem Fragezeichen hinter dem Datentyp.
int eineZahl = null; //Das wäre nicht möglich, weil man einem Integer nicht null zuweisen kann
int? eineZahl = null; //Hui, Dartmagie! Plötzlich können wir dem Integer auch den Wert null geben
onChanged da oben hat Funktionalitäten, auf die ich nicht näher eingehen will (weil ich sie mir selbst noch nicht genauer angesehen habe), die mit einem übergebenen null greifen. Deshalb ist der Datentyp nullierbar (ich bin richtig stolz auf dieses Wort).
Das Ausrufezeichen im Code oben ist ein null-check. Dazu hab ich jetzt noch nicht viel Literatur gefunden, aber ich nehme an, dass es darum geht, dass bei einer Zuweisung an eine nicht-nullierbare Variable - die checked ja ist - erst mal überprüft werden muss, ob da ein null in der Zuweisung steckt, oder nicht. Wahrscheinlich würde hier eine Exception geworfen werden, wenn wir versuchen würden, checked null zuzuweisen.
Ich weiß, wenn du neu in der Programmierung bist, war das wahrscheinlich ziemlich viel, aber sei nicht frustriert, wenn du das nicht verstanden hast. Das kommt noch. Richtete sich eher an die Leute, die schon ein wenig Erfahrung haben.
Bester Kommentar, den ich jemals gelesen habe. Vielen Dank.
Hast du zufällig auch den ganzen überarbeiteten Code?
Komme nicht ganz weiter. 😅
Super Tutorial! Habe ne Weile gebraucht, um Futter zu verstehen, danach haben eure Videos echt geholfen.
Ich verstehe, dass die Videos für einige zu schnell wirken. Allerdings muss man sich auch selbst mit dem Programm befassen, dann wird das schon!
Mal wieder ein sehr geiles Video💪
Die Sachen werden soo gut erklärt und man kann alles verstehen👍
WEITER SOO👍💪💪
Danke 💪
@STARTUP TEENS Ich finde die Reihe echt gut, würde mir nur wünschen, dass noch mehr auf die Stylisierungen eingegangen wird. Wie z.B. habt ihr die Checkbox Rund in Gelb hinbekommen, habe dazu schon bei StackOverflow geschaut, aber leider keine für mich brauchbare antwort gefunden.
Super Leute aber...
ihr seid sehr schnell, ich muss jedes Video ein paarmal ansehen und verstehe viele Fachbegriffe nicht. Macht doch die Videos etwas länger und erklärt erstmal die Fachbegriffe, bevor ihr sie verwendet. Und oftmal ist der Code der angezeigt wird auf einmal total anders. ich wollte mitschreiben, und als ich auf Github nachgesehen habe ist das etwas ganz anderes. dann kopiere ich da den Code raus und in Android Studio wieder rein, aber ich habs ja nicht geschrieben, und viel weniger Bezug dazu...
Fazit, ich bin zu langsam, ihr seid zu schnell...
Top erklärt, wie immer! :)
Danke 😎
Hey, ich bräuchte Hilfe, ich habe bei
"leading: Checkbox(
value: false,
),"
ein Fehler, Checkbox wird als Fehler eingezeigt: "The named parameter 'onChanged' is required", was kann ich machen?
Ich habe das selbe Problem. Hast du mittlerweile eine Lösung dafür gefunden?
Damit man den Code testen kann trickst man das so aus:
Checkbox(value: false, onChanged: (bool? value) { }, )
Das Video können nur Leute verstehen, die Programmiererfahrung haben. Auch mit Erfahrung fliegt ihr nur so durch die Begriffe:D
Wombat Mensch hey :) wir machen ja extra eine ganze Videoreihe zu dem Thema, damit man auch ohne Erfahrung den Durchblick behält! Also einfach die Flutter Tutorial Videos 1-7 schauen wenn was unklar ist :D
@@STARTUPTEENS Ich habe die Videos gesehen und ich verstehe auch alles. Aber finde trotzdem, dass die Videos nicht für Anfänger geeignet sind. Die Videos sind gut, weil sie sehr kompakt sind und eine Menge Informationen enthalten, um einen ersten Einstieg in Flutter und Dart zu bekommen, aber eben zu kompakt für viele Anfänger. Viele Hintergrundinformation zur Dartsprache fehlen, damit man sie wirklich durchdringen könnte. Aber ich schaue weiter und lasse mich überraschen. Danke für eure Mühe.
@@konradcurth52 Jo, muss ich leider zustimmen. Ich versuche mich durch mehrmaliges Anschauen jedes einz. Videos und ergänzende Ressourcen (z.b. die Videos von Academind) da durch zuhangeln. Hast du weitere Tipps, was man sich mal anschauen sollte?
Danke, das Video ist super!!!
Dankeee
lol gar nicht gemerkt dass wieder neue Video gemacht werden 😂
Einfach nur super erklärt !:)
Geiles video ! Ich versuche es gerade zu lernen c:
Viel Erfolg 💪
Was ist der Unterschied von dem ganzen zu einer normalen Java Methode? Bzw. zwischen Flutter und Java allgemein? Mir kommt das Ganze hier nur sehr bekannt vor aus dem Informatikunterricht, wo wir "normal" Java programmieren mit BlueJ
Flutter ist ein Framework. Stell dir das vor wie ein Bilderrahmen. Das Bild was dort rein kommt ( deine App ) muss aber bestimmte Voraussetzungen haben. Z.B Höhe, Breite Papierdicke. Solange du das erfüllt kannst du alles reinmachen was du möchtest.
Programmieren tust du aber mit Dart. Dart ist das Gegenstück zu deinem Java ,
BlueJ das Gegenstück zu Android Studio :)
Viele Videos sind verständlich doch hier verstehe ich nur Bahnhof. Heilige Makrele.
Die Funktionalität des contentpadding habt ihr schon falsch dargestellt, da es nur den Content im ListTile verschiebt, aber nicht die returnten Container in Body: Column! Wir kann man das denn am besten machen?
ich habe es so gelöst, dass ich folgendes als SingleToDo returne: Container( padding: Edgeinsets.all(8.0), child: Container(DreRest))
Mega Geil erklärt!!
Hey, ich programmiere gerade eine App un habe genauso einen Constuctor erstellt:
final String title;
const SingleGroup(this.title);
Aber hier beim title wird mir ein Fehler angezeigt:
title: Text(title),
Fehler: Evaluation of this constant expression throws an exception.dart(const_eval_throws_exception)
Arguments of a constant creation must be constant expressions.
Try making the argument a valid constant, or use 'new' to call the constructor.dartconst_with_non_constant_argument
Wie kann ich das beheben. Denn ich sitze jetzt schon echt lange daran xD
Sollte eigentlich schon so funktionieren. Falls das Problem noch besteht, könntest du mir den Code des gesamten Widgets geben? Dann kann ich mal drüberschauen. :)
Super Video! Ich habe nur eine Frage: bei mir rücken bei dem contentPadding die ListTiles zwar weiter auseinander, aber die Lücke ist in der selben Farbe wie das ListTile... Hat wer nen Lösungsansatz, oder muss ich ne border drum rum machen?
Du könntest einen neuen Container mit padding in der Hierarchie über dem Widget mit dem Color Attribut hinzufügen
@@jannikn.8505 Danke :)
@@jannikn.8505 Könntest du evtl genauer beschreiben wo du den Container einfügst?
bei mir wird bei "contentPadding" kein Abstand zwischen den Listen Einträgen erstellt.. Die Einträge werden einfach nur höher. Kann mir jemand helfen D:
Ich habe es gelöst indem ich "margin: const EdgeInsets.only(bottom: 10)," benutzt habe. Vielleicht kann das ja irgendwer gebrauchen haha
Hey kann mir jemand weiterhelfen? In diesem Part habe ich gelernt, wie man sein eigenes Widget selbst definiert und wie man den Widgets von außen Argumente übergibt (Damit wie im Beispiel nicht überall Tomate steht). So das habe ich mit einer eigenen Liste und einem eigenen Beispiel ausprobiert und das hat wunderbar geklappt. Jetzt meine Frage: Mal angenommen ich habe eine Liste in der 2 unterschiedliche Texte in einer Zeile stehen sollen. Zum Beispiel, wie im Tutorial, das Produkt und zusätzlich noch ein weiterer Text, zum Beispiel die Marke des Produktes. Wie kann ich also mein eigenes Widget definieren und oben 2 oder mehr Argumente in einer Zeile ausgegeben bekommen? Schwer zu erklären xD
Beispiel:
die Liste soll folgendes ausgeben:
|Checkbox| |Produkt| |Marke| |Icon|
✅ Tomate Heinz 🗑️
✅ Saft Hohes C 🗑️
Kann mir jemand weiterhelfen. Ansonsten habe ich bisher alles verstanden.
Als Erstes braucht dein Widget noch einen zweiten String für den Text - auch den Konstruktor erweitern. Dann kannst du im ListTile > title anstatt dem Text-Widget ein Row-Widget verwenden und darin deine beiden Texte anzeigen lassen. Dann die Ausrichtung der Row auf bspw. spaceEvenly stellen und schon sollte dein Widget zwei Texte anzeigen. ;)
Habe Heute das erste mal mit programmieren zu tun. Ich finde es sehr interessant, aber echt schwer! Ich versteh nur Bahnhof :D Hätte gerne so ein Copy-Paste Baukasten, idem ich nur Namen, schriftarten, bilder etc. veränder muss.
Programmieren ist auch nicht leicht... Zumindest am Anfang nicht. Ich würde deshalb empfehlen die Grundlagen erstmal in einer leichten Programmiersprache zu lernen. Ich zum Beispiel habe mit Webentwicklung angefangen, wenn man z.b. Javascript oder PHP versteht hat man schon einmal grundlegende Erfahrung gesammelt. Nach Skriptsprachen wie eben PHP und Javascript, habe ich mit python angefangen... Und mich dann auch komplexeren Programmiersprachen gewidmet.
Übrigens gibt es so einen Baukasten, nennt sich Supernova und der arbeitet auch mit Flutter Code, Nachteil ist neben dem Fakt das man dafür bezahlen muss, dass man nicht so individuelle Apps Programmieren kann.
obwohl ich etwas programmieren kann, denke ich mir bei euch nur: bekommt man noch den Code zu sehen?
Soso, aber YT kannste nicht bedienen? Der Link zum Code ist Zeile Nummero 1, wenn man auf "Mehr ansehen" klickt.
Das Video ist super aber ich brauche Hilfe. Mir wird dieser Fehler angezeigt: Context: Found this candidate, but the arguments don't match.
const SingleToDo(this.title);
Was soll ich tun? Jemand eine Idee?
Habs gelöst ;)
@@marvinbecker3933 wie?
Ok also in der Folge habe ich quasi gar nichts verstanden. Keine Ahnung wo man was einfügen soll.
Ja du hast recht, mir fällt es nur leicht weil ich schon programmiererfahrungen habe.
...
...
...
...
Ist echt ein sehr schlechtes Video, weil man absolut nicht mitkommt und es sehr viele Fehlermeldungen gibt die man selber lösen muss.
Ganz starkes Deabo