StatefulWidget
StatefulWidget классы абалды сактаган виджеттерди түзүү үчүн иштелип чыккан. Ошол эле учурда, StatefulWidget классынын объекттери өзгөрүлбөс болгонуна карабастан, алардын абалы өзгөрүлмө.
Абал - бул виджет түзүлгөндө синхрондуу окула турган жана виджеттин циклинин жүрүшүндө өзгөрө турган кээ бир маалымат. Абалы объект жазылган башка объекттерде сакталышы мүмкүн.
State объекттер алкак тарабынан чакырылган жана аларды StatefulWidget виджетине байлаган createState ыкмасын колдонуу менен түзүлөт .
Мисалы, эң жөнөкөй StatefulWidget виджетин аныктайлы:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Counter(),
appBar: AppBar(title: Text("StatefulWidget
"),),),
), ); }
class Counter extends StatefulWidget{
Counter({ super.key});
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter>{
int value = 0;
@override
Widget build(BuildContext context) {
return Text(
"Value: $value", style: TextStyle(fontSize: 22),
); } }
Ошентип, бул жерде StatefulWidget тен калган Counter классы аныкталган.
Анын конструктору бир параметрди камтыйт - key, бирок керек болсо, биздин муктаждыктарыбыздын негизинде башка параметрлерди аныктай алабыз.
Ошондой эле виджет классы ошол виджеттин абалын кайтарып бере турган createState() ыкмасын жокко чыгарышы керек
@override
_CounterState createState() => _CounterState();
Бул учурда, ал класстын объекти болуп саналат _CounterState. (Алдына сызыкча (_) коюлган класстар же класс мүчөлөрү башка китепканалардын класстары үчүн купуя болуп саналат.)
Абалы класстын өзү виджет классынын классы тарабынан терилген State классынан алынган.
class _CounterState extends State<Counter>{
Класс өзү value шарттуу түрдө абалын класс сактаган маалыматтарды көрсөткөн өзгөрмө аныктайт.
int value = 0;
Биз ошондой эле виджетти кайтарып турган build() ыкмасын жокко чыгарышыбыз керек :
Widget build(BuildContext context) {
return Text(
"Value: $value", style: TextStyle(fontSize: 22),
); }
Text бул жерде биз жөн гана өзгөрмөнүн маанисин көрсөткөн виджетти кайтарабыз value. Бирок табигый түрдө кайтарылган виджет иерархиясы болушу мүмкүн.
Андан кийин Counter виджети Scaffold элементиндеги тиркемеге киргизилет:
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Counter(),
Натыйжада, колдонмо башталганда, биз маани өзгөрмөнүн мааниси менен текстти көрөбүз
Бирок StatefulWidget тин негизги идеясы - биз анын абалын өзгөртө алабыз. Ошондуктан, келгиле, баскычты басуу менен маани өзгөрмөсүнө өзгөртүү киргизели:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Counter(),
appBar: AppBar(title: Text("StatefulWidget")),)
));
}
class Counter extends StatefulWidget{
Counter({ super.key});
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter>{
int value = 0;
@override
Widget build(BuildContext context) {
return ElevatedButton(
child: Text("Value: $value", style: TextStyle(fontSize: 22)),
onPressed:(){ setState(() {
value++;
});}
);
}
}
Эми, жөнөкөйлүк үчүн, маани өзгөрмөнүн мааниси баскычта текст катары көрсөтүлөт. Баскыч басылганда, маанинин маанисин бир көбөйтүүчү функция чакырылат. Өзгөргөнүн көрсөтүү үчүн, виджет State.setState() ыкмасын чакырат. Бул ыкма эч кандай параметрлерди кабыл албаган жана эч нерсе кайтарбаган функцияга өтөт. Жана анын ичинде биз нарктын маанисин өзгөртө алабыз.
Натыйжада, баскычты басуу менен өзгөрмө маанинин мааниси жогорулайт:
Маалыматтарды State өткөрүү
Зарыл болгон учурда маалыматтар Мамлекеттик объектке сырттан берилиши мүмкүн. Бул учурда, которуу StatefulWidget аркылуу жүргүзүлөт. Мисалы, мамлекет сырттан баштапкы маалыматтарды алгыдай кылып, жогорудагы мисалды өзгөртөлү:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Column(children:[
Counter(value: 4, increment: 2),
Counter(value:-1, increment: 1)
]),
appBar: AppBar(title: Text("StatefulWidget")),)
));
}
class Counter extends StatefulWidget{
int value = 0;
int increment = 1;
Counter({ super.key, required this.value, required this.increment});
@override
_CounterState createState() => _CounterState(this.value, this.increment);
}
class _CounterState extends State<Counter>{
int value = 0;
int increment = 1;
_CounterState(this.value, this.increment);
@override
Widget build(BuildContext context) {
return ElevatedButton(
child: Text("Value: $value", style: TextStyle(fontSize: 22)),
onPressed:(){ setState(() {
value = value + increment;
});} ); } }
Бул учурда, абалга жаңы өзгөрмө кошулду increment, ал аркылуу маани өзгөрмөнүн мааниси көбөйөт. Бул өзгөрмөлөр үчүн маанилерди сырттан алуу үчүн конструктор аныкталган._CounterState(this.value, this.increment)
Мамлекеттик объектти түзүүдө Counter виджети конструкторго тиешелүү маалыматтарды өткөрүп берет:
_CounterState createState() => _CounterState(this.value, this.increment);
Ошол эле учурда, Counter виджетинин өзү конструктордун жардамы менен бул баалуулуктарды сырттан алат:
Counter({ super.key, required this.value, required this.increment});
Натыйжада, виджетти колдонууда биз ага ар кандай маалыматтарды бере алабыз:
Column(children:[
Counter(value: 4, increment: 2),
Counter(value:-1, increment: 1)
])
Виджет алуу
Штаттын ичиндеги виджет касиетин колдонуу менен , StatefulWidgetке кире аласыз, ал Мамлекеттик объекти төмөнкүлөргө милдеттүү:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Column(children:[
Counter(increment: 2),
Counter(increment: 1),
]),
appBar: AppBar(title: Text("StatefulWidget ")),)
));
}
class Counter extends StatefulWidget{
int increment = 1;
Counter({ super.key, required this.increment});
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter>{
int value = 0;
@override
Widget build(BuildContext context) {
return ElevatedButton(
child: Text("Value: $value", style: TextStyle(fontSize: 22)),
onPressed:(){ setState(() {
value = value + widget.increment;
});} ); } }
Бул учурда, кошумча өзгөрмө Counter классынын ичинде гана аныкталат жана ага widget.incrementCounter widget виджети деген туюнтма аркылуу жетүүгө болот. Ошо сыяктуу эле, эгер бар болсо, виджеттен башка талааларга жана ыкмаларга кире аласыз.
Жогорудагы мисалдарда абалды өзгөртүүнүн бардык логикасы -дан функцияда топтолгон onPressed. Бирок бул иш-аракеттердин бардыгын өзүнчө бир ыкма менен алып салууга болот:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Column(children:[
Counter(increment: 2),
Counter(increment: 1),
]),
appBar: AppBar(title: Text("StatefulWidget ")),)
));
}
class Counter extends StatefulWidget{
int increment = 1;
Counter({ super.key, required this.increment});
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter>{
int value = 0;
increaseValue(){
setState(() {
value = value + widget.increment;
});
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
child: Text("Value: $value", style: TextStyle(fontSize: 22)),
onPressed:(){ increaseValue();}
);
}
}
Эгерде бардык аракеттер жайгаштырылган ыкма эч нерсе кайтарбаса жана эч кандай параметрди кабыл албаса, башкача айтканда, ал аныктамага туура келсе onPressed чёанда onPressed параметрине функцияны түздөн-түз дайындай аласыз:
ElevatedButton(
child: Text("Value: $value", style: TextStyle(fontSize: 22)),
onPressed: increaseValue
);