class AddTaskPage extends StatelessWidget {
const AddTaskPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final logic = Get.put(AddTaskLogic());
final state = Get.find().state;
return Scaffold(
appBar: AppBar(
backgroundColor: Tcolor.barBackgroudColor,
elevation: 0,
),
body: _addTaskContent(state),
);
}
_addTaskContent(AddTaskState addTaskState) {
return GetBuilder(builder: (logic) {
return Container(
child: Column(
children: [
//任务类型 0-工作 1-学习 2-生活
Container(
key: logic.typeKey,
child: InputFied(
fieldwidth: 300,
hintText: "请选择任务类型",
controller: addTaskState.contentController,
iconWidget: InkWell(
child: Icon(addTaskState.typeExpand?Icons.expand_less_outlined:Icons.expand_more,color: Colors.grey,size: 18,),
onTap: (){
print("弹出任务类型选择框");
logic.selectTypePop();
},
)
),
),
],
),
);
});
}
}
class AddTaskLogic extends GetxController {
final AddTaskState state = AddTaskState();
GlobalKey typeKey = GlobalKey();
//弹出任务类型选择框
selectTypePop(){
state.typeExpand=!state.typeExpand;
update();
RenderBox typeBox = typeKey.currentContext!.findRenderObject() as RenderBox;
print("要开始构建了Pop了");
PopToastManager().buildUI(
context: Get.context!,
isClickDiss: true,
X: typeBox.localToGlobal(Offset.zero).dx + 28 + 76,
Y: typeBox.localToGlobal(Offset.zero).dy + 26,
offx: 0,
offy: 0,
width: 260,
height: 90,
childWidget: ListView.builder(
itemCount: state.taskType.length,
itemBuilder: (context, index) {
print("构建UI");
return Container(
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(60),
child: Container(
width: 13,
height: 13,
decoration: BoxDecoration(
color: state.typeColor[index],
),
),
),
SizedBox(width: 20,),
Text(state.taskType[index]),
],
),
);
},
),
);
update();
}
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
//封装一个构造弹窗类
/*OverlayEntry 可以实现悬浮窗效果*/
class PopToastManager{
/*OverlayEntry类型的私有实例变量*/
OverlayEntry? _overlayEntry;
/*PopToastManager类型的私有实例变量*/
static PopToastManager? _manager;
/*PopToastManager的私有构造函数,用于创建新实例*/
PopToastManager._();
/*PopToastManager的工厂构造函数,用于创建类的实例,并保证只创建一个实例*/
factory PopToastManager(){
if(_manager==null){
_manager=PopToastManager._();
}
return _manager!;
}
/*在buildUI()函数内部创建overlayEntry对象并且插入到overlayEntry中*/
void buildUI(
{
required BuildContext context,
required bool isClickDiss,
required double X,
required double Y,
required double offx,
required double offy,
required double width,
required double height,
required Widget childWidget,
Function? dismissCallBack/*取消的回调函数*/
}){
//创建 overlayEntry
OverlayEntry overlayEntry=OverlayEntry(
builder: (context){
print("开始构建overlayEntry");
return GestureDetector(
behavior:HitTestBehavior.opaque ,
/*点击事件*/
onTap: (){
/*如果可以点击*/
if(isClickDiss){
/*取消回调函数不为空则调用取消回调函数*/
if (dismissCallBack != null) {
dismissCallBack();
}
/*蒙层取消函数*/
dissmiss();
}
},
/*子组件*/
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.transparent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Container(height: Y,),
SizedBox(height: Y,),
Container(
margin: EdgeInsets.fromLTRB(offx + X,offy, 0, 0),
width: width,
height: height,
child: childWidget,
),
],
),
),
);
});
this._overlayEntry = overlayEntry;
//插入到 Overlay中显示 OverlayEntry
Overlay.of(context)!.insert(overlayEntry);
/*final overlay = Overlay.of(context);
if (overlay != null) {
overlay.insert(overlayEntry);
} else {
print('Overlay is null');
}*/
}
void dissmiss(){
if(this._overlayEntry != null){
print("蒙层消失");
this._overlayEntry!.remove();
this._overlayEntry = null;
}
}
}
根据打印的语句可以得知,代码根本没有开始构建OverlayEntry(builder:(context){})
1、于是我首先在PopToastManager()类buildUI()方法中添加对context是否为空的判断
此时运行结果
说明:此时传入的context不为空但是Overlay.of(context)为空
为什么会这样?
首先:需要知道Overlay.of(context)意味着什么?
据搜索:Overlay 是一个可以在应用程序中显示浮动元素的特殊 Widget。Overlay.of(context)
是Flutter框架中的一个方法,用于获取指定上下文中最近的Overlay,Overlay.of(context)
方法返回的对象可以用于向 Overlay 中添加浮动元素。
如果 Overlay.of(context)
返回 null
,则表示指定上下文中没有找到 Overlay。这通常是由于没有在该上下文的 Widget 树中添加 Overlay 导致的。在使用 Overlay.of(context)
之前,需要确保在应用程序的 Widget 树中添加了 Overlay。
此时可推测:
1、在上下文中没有添加Overlay,所以不能向Overlay 中添加浮动元素x
2、上下文出现了问题
试解决问题(1):
将context作为参数传入进selectTypePop()