У меня есть StateFul
виджет и class
с конструктором. Этот класс имеет functions
, и каждая функция просто возвращает widget
. Я хочу получить доступ к состоянию виджета Stateful
изнутри функции другого class
. Вот почему я использую context.findAncestorStateOfType<>()
.
class MyHomePage extends StatefulWidget {
static MyHomePageState of(BuildContext context) => context.findAncestorStateOfType<MyHomePageState>();
@override
MyHomePageState createState() => MyHomePageState();
}
Внутри initState()
виджета Stateful
я инициализирую конструктор другого class
с параметрами. Одна из функций имеет GestureDetector
для виджета. Внутри onTap() GestureDetector
я пытался вызвать изменение значения переменной в виджете Stateful
. Это где я получаю нулевую ошибку. Я попытался установить конструктор из build()
, но я получаю ту же ошибку. Пожалуйста, помогите мне с этим. Заранее спасибо.
Журнал ошибок :
The following NoSuchMethodError was thrown while handling a gesture:
The setter 'choosingDestinationFromMap=' was called on null.
Receiver: null
Tried calling: choosingDestinationFromMap=true
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1 MapHelper.destinationPointWidget.<anonymous closure> (package:google_map/map_helper.dart:511:42)
#2 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
#3 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
#4 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#30707
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(140.4, 170.2)
finalLocalPosition: Offset(140.4, 23.1)
button: 1
sent tap down
initState () :
@override
void initState() {
super.initState();
controller1 =
AnimationController(vsync: this, duration: Duration(milliseconds: 200));
controller2 =
AnimationController(vsync: this, duration: Duration(milliseconds: 150));
controller2_1 =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
controller3 =
AnimationController(vsync: this, duration: Duration(milliseconds: 150));
controller3_1 =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
offset1 = Tween<Offset>(begin: Offset(0.0, -1.0), end: Offset.zero).animate(controller1);
offset2 = Tween<Offset>(begin: Offset(0.0, -1.0), end: Offset.zero).animate(controller2);
offset2_1 = Tween<Offset>(begin: Offset(0.0, -0.40), end: Offset.zero).animate(controller2_1);
offset3 = Tween<Offset>(begin: Offset(0.0, -1.0), end: Offset.zero).animate(controller3);
offset3_1 = Tween<Offset>(begin: Offset(0.0, -0.40), end: Offset.zero).animate(controller3_1);
mapHelper = MapHelper(controller1, controller2, controller2_1, controller3,
controller3_1, offset1, offset2, offset2_1, offset3,
offset3_1, textController1, textController2, context);
}
Другой класс :
class MapHelper {
AnimationController controller1;
AnimationController controller2;
AnimationController controller2_1;
AnimationController controller3;
AnimationController controller3_1;
Animation<Offset> offset1;
Animation<Offset> offset2;
Animation<Offset> offset2_1;
Animation<Offset> offset3;
Animation<Offset> offset3_1;
TextEditingController textController1;
TextEditingController textController2;
BuildContext context;
MapHelper(this.controller1, this.controller2, this.controller2_1,
this.controller3, this.controller3_1, this.offset1, this.offset2,
this.offset2_1, this.offset3, this.offset3_1, this.textController1,
this.textController2, this.context);
destinationPointWidget() {
return SlideTransition(
position: offset3,
child: Align(
alignment: Alignment.topCenter,
child: Container(
color: Colors.white,
height: 110,
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SlideTransition(
position: offset3_1,
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.black26),
),
child: Row(
children: <Widget>[
Flexible(
flex: 1,
child: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.black,
),
onPressed: () {
controller3.reverse();
controller3_1.reverse();
controller1.forward();
},
),
),
SizedBox(width: 10,),
Flexible(
flex: 7,
child: TextField(
controller: textController1,
cursorRadius: Radius.circular(10),
style: TextStyle(
fontSize: 17,
),
decoration: InputDecoration(
hintText: "Choose destination point",
border: InputBorder.none,
),
onSubmitted: null,
),
),
],
),
),
),
),
SizedBox(height: 6,),
GestureDetector(
child: Container(
padding: EdgeInsets.only(bottom: 8),
margin: EdgeInsets.only(left: 8),
child: Row(
children: <Widget>[
Flexible(
flex: 1,
child: Container(
alignment: Alignment.center,
height: 40,
child: CircleAvatar(
radius: 15,
backgroundColor: Colors.black12,
child: Icon(Icons.map, color: Colors.black54, size: 20,),
),
),
),
SizedBox(width: 10,),
Flexible(
flex: 8,
child: Container(
height: 40,
alignment: Alignment.centerLeft,
child: Text(
"Choose on map",
style: TextStyle(
fontSize: 16,
),
),
),
),
],
),
),
onTap: () {
MyHomePage.of(context).choosingDestinationFromMap = true;
print(MyHomePage.of(context).choosingDestinationFromMap);
MyHomePage.of(context).positionMarkerAtCenter();
},
),
],
),
),
),
);
}
}