既然是关闭按键超出了底图范围导致不能点击,那就让关闭按键不超出就可以了。
可以给底图再添加一个大点的底图,这两个底图作为一个整体,关闭按键就可以点击了
如图,下面添加了一个黑色的底图用来扩充原来的底图范围,白色关闭按键就可以点击得到了
return Material(
color: Colors.transparent,
child: Center(
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.bottomCenter,
children: [
Stack(
alignment: Alignment.center,
children: [
Container(
color: Colors.black,
height: 480.r,
width: Global.screenWidth,
),
Stack(
alignment: Alignment.topCenter,
children: [
Container(
margin: EdgeInsets.only(bottom: 50.r),
height: 344.r,
width: 332.r,
decoration: BoxDecorationUtil().setFillBoxDecorationImg(
'assets/images/bg_sign_in_result.png')),
Positioned(
top: 93.r,
child: Column(
children: [
Text(
S.current.check_in_congratulation,
style: TextStyle(
color: const Color(0xFFF96281),
fontSize: 24.sp,
fontWeight: FontWeight.w700),
),
Stack(
alignment: Alignment.topLeft,
children: [
Container(
width: 265.r,
height: 90.r,
margin: EdgeInsets.only(top: 15.r),
alignment: Alignment.center,
constraints:
BoxConstraints(maxHeight: 105.0.r),
decoration: BoxDecorationUtil()
.setFillBoxDecorationImg(
'assets/images/bg_sign_in_gift.png'),
child: ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.only(),
itemCount: widget.signInGetResult
.signInGetResultItem?.length,
scrollDirection: Axis.horizontal,
itemBuilder: (contexts, index) {
return Stack(
alignment: Alignment.bottomCenter,
children: [
Stack(
children: [
Container(
child: Column(
mainAxisSize:
MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Container(
width: 54.0.r,
height: 54.0.r,
alignment:
Alignment.center,
margin: EdgeInsets.only(
left: widget
.signInGetResult
.signInGetResultItem
?.length ==
2
? 32.0.r
: widget.signInGetResult.signInGetResultItem
?.length ==
3
? 12.0.r
: 12.0.r,
right: widget
.signInGetResult
.signInGetResultItem
?.length ==
2
? 32.0.r
: widget.signInGetResult.signInGetResultItem
?.length ==
3
? 12.0.r
: 12.0.r,
bottom: 17.r),
child: BackgroundWall(
avtarUrl: widget.signInGetResult
.signInGetResultItem?[index].icon,
)
// child: Image(
// image: AssetImage(
// 'assets/images/icon_sign_in_turntable.png'),
// ),
),
// TopPadding(10.0.r),
],
),
),
],
),
Positioned(
bottom: 13.5.r,
child: ContentText(
'${widget.signInGetResult.signInGetResultItem?[index].qtyText}',
12.0.sp,
Colors.white,
fontWeight: FontWeight.w700,
),
),
],
);
})),
Positioned(
top: 15,
left: -2,
child: Image(
image: widget.todayIndex == 1
? const AssetImage(
'assets/images/icon_sign_in_first.png')
: widget.todayIndex == 2
? const AssetImage(
'assets/images/icon_sign_in_second.png')
: widget.todayIndex == 3
? const AssetImage(
'assets/images/icon_sign_in_three.png')
: widget.todayIndex == 4
? const AssetImage(
'assets/images/icon_sign_in_four.png')
: widget.todayIndex == 5
? const AssetImage(
'assets/images/icon_sign_in_five.png')
: widget.todayIndex == 6
? const AssetImage(
'assets/images/icon_sign_in_six.png')
: const AssetImage(
'assets/images/icon_sign_in_seven.png'),
width: 30.r,
height: 30.r,
),
),
],
),
GestureDetector(
onTap: () {
launchUrl(
Uri.parse(
"http://www.hayyachat.com/vn/activity/free_lottery"),
);
},
child: Container(
margin: EdgeInsets.only(top: 23.r),
alignment: Alignment.center,
height: 50.r,
width: 265.r,
decoration: BoxDecorationUtil()
.setFillBoxDecorationImg(
'assets/images/icon_sign_in_press.png'),
child: Text(
S.current.check_in_lottery,
style: TextStyle(
color: const Color(0xFFFFF9E8),
fontSize: 20.sp,
fontWeight: FontWeight.w600),
),
),
),
],
),
)
],
)
],
),
Container(
child: GestureDetector(
onTap: () {
MyRouter.pop(context);
},
child: Container(
padding: EdgeInsets.only(
right: 15.r, top: 20.r, bottom: 45.r, left: 15.r),
child: GestureDetector(
onTap: () {
MyRouter.pop(context);
},
child: Image(
image: AssetImage(
'assets/images/icon_sign_in_close_white.png'),
width: 30.r,
height: 30.r,
),
),
),
),
)
],
),
),
);
//底部弹窗可以这样子处理
import 'dart:convert';
import 'dart:developer';
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:oktoast/oktoast.dart';
import 'package:provider/provider.dart';
import 'package:social_im/utils/loadingUtil.dart';
import '../../../common/Global.dart';
import '../../../common/avatar.dart';
import '../../../common/colors.dart';
import '../../../common/globalEventBus.dart';
import '../../../common/ws/room/ws_room_linker.dart';
import '../../../generated/l10n.dart';
import '../../../http/api.dart';
import '../../../http/http_request.dart';
import '../../../http/net_callback.dart';
import '../../../http/rxhttp.dart';
import '../../../http/utils/NetUtils.dart';
import '../../../http/utils/response.dart';
import '../../../im/user_info.dart';
import '../../../models/archives_info.dart';
import '../../../models/myUserInfo.dart';
import '../../../models/userInfo/userExpandInfo.dart';
import '../../../protobufdart/dart/room/room.pb.dart';
import '../../../provider/user.dart';
import '../../../router.dart';
import '../../../utils/date_util.dart';
import '../../../utils/image_utile.dart';
import '../../../utils/printUtil.dart';
import '../../pay/model/extend.dart';
import '../../widget/myText.dart';
import '../../widget/splitLine.dart';
import '../direct_message_tip.dart';
import 'package:social_im/protobufdart/dart/room/user_extra_info.pb.dart'
as $user_extra;
import 'package:fixnum/fixnum.dart' as $fixnum;
//直播相关界面-用户详情
class DirectUserDetail extends StatefulWidget {
//信息
DirectUserDetailModel? directUserDetailModel;
//来源
int? source;
//是否已关注主播
bool? hasFocusAnchor;
DirectUserDetail(
{Key? key, this.directUserDetailModel, this.source, this.hasFocusAnchor})
: super(key: key);
@override
State<StatefulWidget> createState() => DirectUserDetailState();
}
class DirectUserDetailState extends State<DirectUserDetail> {
bool isFocus = false;
ArchivesInfo? archivesInfo;
UserExpandInfo? userExpandInfo;
MyUserInfo? myUserInfo;
//默认显示
bool showFocusButton = true;
@override
void initState() {
print('详情弹窗${Global.userId} ${widget.directUserDetailModel?.userId}');
//获取是否已关注
if (Global.userId != '${widget.directUserDetailModel?.userId}') {
//点开的不是自己才请求接口
_getFocusState();
}
// getBaseUserInfoApi();
//获取VIP,财富等级和魅力等级
_getExtendInfo(0);
super.initState();
}
@override
void dispose() {
super.dispose();
}
//获取性别1男 2女
int getSex() {
//默认是女
int sex = 2;
if (widget.directUserDetailModel != null) {
if (widget.directUserDetailModel!.sex != null) {
sex = widget.directUserDetailModel!.sex ?? 2;
} else {
if (archivesInfo != null) {
if (archivesInfo!.sex != null) {
sex = archivesInfo!.sex ?? 2;
}
}
}
} else {
if (archivesInfo != null) {
if (archivesInfo!.sex != null) {
sex = archivesInfo!.sex ?? 2;
}
}
}
return sex;
}
//获取年龄
int getAge() {
int age = 0;
print(
'获取年龄是${widget.directUserDetailModel?.age} ${archivesInfo?.birthday}');
if (widget.directUserDetailModel != null) {
if (widget.directUserDetailModel!.age != null) {
age = widget.directUserDetailModel!.age!;
} else {
if (archivesInfo != null) {
if (archivesInfo!.birthday != null) {
age = UserInfoUtil().getAge(archivesInfo!.birthday ?? 0);
}
}
}
} else {
if (archivesInfo != null) {
if (archivesInfo!.birthday != null) {
age = UserInfoUtil().getAge(archivesInfo!.birthday ?? 0);
}
}
}
return age;
}
//获取昵称
getName() {
String name = '';
if (widget.directUserDetailModel != null) {
if (widget.directUserDetailModel!.nickName != null) {
name = widget.directUserDetailModel!.nickName ?? '';
}
}
return name;
}
//获取头像
getAvatar() {
String avatar = '';
if (widget.directUserDetailModel != null) {
if (widget.directUserDetailModel!.avatar != null) {
avatar = widget.directUserDetailModel!.avatar ?? '';
}
}
return avatar;
}
//获取财富等级
int getWealthLevel() {
int level = 0;
if (userExpandInfo != null) {
if (userExpandInfo!.wealth_level != null) {
level = userExpandInfo!.wealth_level ?? 0;
}
}
return level;
}
//获取魅力等级
int getCharmLevel() {
int level = 0;
if (userExpandInfo != null) {
if (userExpandInfo!.charm_level != null) {
level = userExpandInfo!.charm_level ?? 0;
}
}
return level;
}
///是否vip
bool getVip() {
bool _isVip = false;
if (userExpandInfo != null) {
_isVip = (userExpandInfo!.vip_level ?? 0) > 0 &&
(userExpandInfo!.vip_expiration_time ?? 0) > DateUtil.getNowDateS();
}
return _isVip;
}
///是否显示关注按键
showFocus() {
///默认展示
bool isShow = true;
if (showFocusButton == false) {
//优先显示点击的状态
isShow = false;
} else {
if (Global.userId == '${widget.directUserDetailModel?.userId}') {
//自己就不显示关注按键
isShow = false;
} else {
//点击主播头像时
if (widget.source == 1) {
if (widget.hasFocusAnchor == true) {
//已经关注了
isShow = false;
} else {
//还没关注主播
isShow = true;
}
} else {
//拉接口获取判断
if (archivesInfo != null) {
if (archivesInfo!.is_focus != null) {
if (archivesInfo!.is_focus == true) {
isFocus = false;
} else {
isFocus = true;
}
}
}
}
}
}
mySetState(() {});
return isShow;
}
mySetState(callBack) {
if (mounted) {
setState(() {
callBack();
});
}
}
///获取金币、钻石等扩展信息
void _getExtendInfo(int delay) {
print('===========获取金币、钻石等扩展信息===========');
Future.delayed(Duration(milliseconds: delay)).then((value) {
RxHttp<UserExpandInfo>()
..init()
..setBaseUrl(Api.BUSINESS_BASE_API)
..setPath(Api.API_USER_EXTENDINFO)
..setCacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST)
..setJsonTransFrom(
(p0) => UserExpandInfo.fromJson(json.decoder.convert(p0)['data']))
..setParams({"user_id": widget.directUserDetailModel?.userId ?? 0})
..call(NetCallback(onNetFinish: (extend) {
userExpandInfo = extend;
mySetState(() {});
}), server: Servers.businessServer);
});
}
///获取个人信息
getBaseUserInfoApi() {
HttpRequest.intance.postHttpFromBusiness(Api.GET_BASEINFO, (data) {
if (data.isNotEmpty) {
LoadingUtil.dismissLoading();
MyUserInfo user = MyUserInfo.fromJson(data);
}
}, (error, errorCode) {
LoadingUtil.dismissLoading();
}, parameters: {'user_id': widget.directUserDetailModel?.userId ?? 0});
}
///获取好友的档案资料(是否关注)
_getFocusState() {
LoadingUtil.showLoading();
RxHttp<ArchivesInfo>()
..init()
..setBaseUrl(Api.BASE_API)
..setPath(Api.GET_OTHER_ARCHIVES_INFO)
..setJsonTransFrom((data) {
log('加载数据 好友档案------$data');
return ArchivesInfo.fromJson(json.decoder.convert(data)['data']);
})
..setCacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST)
..setParams({"user_id": widget.directUserDetailModel?.userId ?? 0})
..call(
NetCallback(onNetFinish: (archivesInfo) {
LoadingUtil.dismissLoading();
this.archivesInfo = archivesInfo;
mySetState(() {});
// setOtherArchivesInfo(archivesInfo);
}, onCacheFinish: (archivesInfo) {
this.archivesInfo = archivesInfo;
mySetState(() {});
LoadingUtil.dismissLoading();
// setOtherArchivesInfo(archivesInfo);
}, onUnkownFinish: (archivesInfo) {
LoadingUtil.dismissLoading();
}, onNetError: (errorCode, error) {
LoadingUtil.dismissLoading();
showToast('$error ($errorCode)');
}),
server: Servers.microServices);
}
// setOtherArchivesInfo(ArchivesInfo archivesInfo) {
// if (archivesInfo.is_focus != null) {
// if (archivesInfo.is_focus == true) {
// isFocus = true;
// } else {
// isFocus = false;
// }
// }
// }
$fixnum.Int64 _int64(String str) {
assert(str.isNotEmpty);
return $fixnum.Int64.parseInt(str);
}
///请求关注广播
focusAnchor() {
//这个关注是用户观众给主播点关注
//观众信息
Uint8List fromUserData = $user_extra.UserExtraInfo(
userId: _int64('${myUserInfo?.userID}'),
nickname: myUserInfo?.nickName,
avatar: myUserInfo?.faceUrlThumb ?? myUserInfo?.faceUrl,
gender: myUserInfo?.gender,
age: UserInfoUtil().getAge(myUserInfo?.birthday ?? 0),
vip: myUserInfo!.isVip ? 1 : 0,
lang: myUserInfo?.userExpandInfo?.region,
wealthLeve: myUserInfo?.userExpandInfo?.wealth_level,
charmLeve: myUserInfo?.userExpandInfo?.charm_level)
.writeToBuffer();
//主播信息
Uint8List toUserData = $user_extra.UserExtraInfo(
userId: _int64('${widget.directUserDetailModel?.userId ?? 0}'),
nickname: widget.directUserDetailModel?.nickName ?? '',
avatar: widget.directUserDetailModel?.avatar ?? '',
charmLeve: widget.directUserDetailModel?.charmLevel ?? 0)
.writeToBuffer();
RoomUserInfo fromUserInfo = RoomUserInfo(
userId: _int64('${myUserInfo?.userID}'),
role: 1,
userExtraInfo: fromUserData);
RoomUserInfo toUserInfo = RoomUserInfo(
userId: _int64('${myUserInfo?.userID}'),
role: 50,
userExtraInfo: toUserData);
WsRoomLinker.instance.focusMsgReq(fromUserInfo, toUserInfo);
}
///添加/删除关注
addDeleteFriend(bool isAdd, String userId) async {
if (isAdd) {
PrintUtil.prints('${DirectMessageTip.focusAnchorTip} 关注的ID是${userId}');
HttpRequest.intance.postHttp(Api.ADD_FOCUS_FRIEND, (data) {
focusAnchor();
//更新聊天界面的关注状态
EventBusUtil.fire(LiveFocusState());
mySetState(() {});
}, (error, errorCode) {}, parameters: {"user_id": int.parse(userId)});
} else {
HttpRequest.intance.postHttp(Api.DELETE_FOCUS_FRIEND, (data) {
//更新聊天界面的关注状态
EventBusUtil.fire(LiveFocusState());
mySetState(() {});
}, (error, errorCode) {}, parameters: {"user_id": int.parse(userId)});
}
}
@override
Widget build(BuildContext context) {
myUserInfo = Provider.of<UserModel>(context, listen: true).info;
return Material(
color: Colors.transparent,
child: Stack(
alignment: Alignment.bottomCenter,
children: [
GestureDetector(
onTap: () {
MyRouter.pushMyMap(context, MyRouter.friendFilesPage, {
'isContainer': false,
'userID': '${widget.directUserDetailModel?.userId ?? 0}',
});
},
child: Container(
color: Colors.red,
height: 340,
width: 80,
)),
Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20))),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Stack(
clipBehavior: Clip.none,
alignment: Alignment.topCenter,
children: [
ConstrainedBox(
constraints: BoxConstraints(minHeight: 200.r),
child: Container(
color: Colors.white,
margin: const EdgeInsets.only(top: 40),
// color: Colors.transparent,
child: Container(
color: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
margin:
const EdgeInsets.only(top: 10, bottom: 5),
child: Text(
'${getName()}',
style: const TextStyle(
color: Color(0xFF333333), fontSize: 18),
),
),
Container(
margin: const EdgeInsets.only(bottom: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.only(left: 5),
alignment: Alignment.center,
padding: const EdgeInsets.fromLTRB(
5, 2, 5, 2),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Image(
image: AssetImage(getSex() ==
1
? 'assets/images/icon_direct_seeding_male.png'
: 'assets/images/icon_direct_seeding_female.png'),
gaplessPlayback: true,
width: 12,
height: 12),
Text(
'${getAge()}',
style: TextStyle(
fontSize: 9.0,
color: getSex() == 1
? const Color(0xFF569BF7)
: const Color(0xFFFF528D),
),
)
]),
decoration: BoxDecorationUtil()
.setFillBoxDecoration(
getSex() == 1
? const Color(0x26519EF1)
: const Color(0x33FF0087),
10.0)),
if (getVip())
Container(
margin: const EdgeInsets.only(left: 13),
padding: const EdgeInsets.only(
left: 5,
right: 5,
top: 2,
bottom: 2),
decoration: BoxDecoration(
color: const Color(0xFFC7B7F5),
borderRadius:
BorderRadius.circular(50)),
child: Row(
children: [
Container(
margin: const EdgeInsets.only(
right: 3),
width: 11,
height: 11,
child: ImageUtile.imageWidget(
"assets/images/icon_direct_seeding_vip.png"),
),
const Text(
'VIP',
style: TextStyle(
color: Color(0xFFA48DFB),
fontSize: 9),
)
],
),
),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Stack(
alignment: Alignment.centerRight,
children: [
Container(
height: 70,
width: 124,
decoration: BoxDecoration(
color: const Color(0xFFEAE5F8),
borderRadius:
BorderRadius.circular(6)),
margin:
const EdgeInsets.only(bottom: 25),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(
left: 5),
alignment: Alignment.center,
padding:
const EdgeInsets.fromLTRB(
5, 2, 5, 2),
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
ConstrainedBox(
constraints:
const BoxConstraints(
maxWidth: 80),
child: const Text(
'财富等级1',
style: TextStyle(
color:
Color(0xFF333333),
fontSize: 14),
),
),
Container(
padding:
const EdgeInsets.only(
left: 5,
right: 5,
top: 2,
bottom: 2),
margin:
const EdgeInsets.only(
top: 3),
decoration: BoxDecoration(
color: const Color(
0xFFC7B7F5),
borderRadius:
BorderRadius
.circular(50)),
child: Row(
children: [
Container(
margin:
const EdgeInsets
.only(
right: 3),
width: 11,
height: 11,
child: ImageUtile
.imageWidget(
"assets/images/icon_direct_seeding_vip.png"),
),
Text(
'${getWealthLevel()}',
style: const TextStyle(
color: Color(
0xFFA48DFB),
fontSize: 12),
)
],
),
),
],
),
),
],
),
),
Container(
margin:
const EdgeInsets.only(bottom: 25),
child: Image(
image: const AssetImage(
'assets/images/icon_direct_seeding_rich.png'),
gaplessPlayback: true,
height: 65.r),
),
],
),
Container(
margin: const EdgeInsets.only(left: 20),
child: Stack(
alignment: Alignment.centerRight,
children: [
Container(
height: 70,
width: 124,
decoration: BoxDecoration(
color: const Color(0x0fff0079),
borderRadius:
BorderRadius.circular(6)),
margin:
const EdgeInsets.only(bottom: 25),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(
left: 5),
alignment: Alignment.center,
padding:
const EdgeInsets.fromLTRB(
5, 2, 5, 2),
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
ConstrainedBox(
constraints:
const BoxConstraints(
maxWidth: 80),
child: const Text(
'魅力等级1',
style: TextStyle(
color: Color(
0xFF333333),
fontSize: 14),
),
),
Container(
padding:
const EdgeInsets.only(
left: 5,
right: 5,
top: 2,
bottom: 2),
margin:
const EdgeInsets.only(
top: 3),
decoration: BoxDecoration(
color: const Color(
0x30FC8B8B),
borderRadius:
BorderRadius
.circular(
50)),
child: Row(
children: [
Container(
margin:
const EdgeInsets
.only(
right: 3),
width: 11,
height: 11,
child: ImageUtile
.imageWidget(
"assets/images/icon_direct_seeding_charm_love.png"),
),
Text(
'${getCharmLevel()}',
style: const TextStyle(
color: Color(
0xFFFB5E80),
fontSize: 12),
)
],
),
),
],
),
),
],
),
),
Container(
margin:
const EdgeInsets.only(bottom: 25),
child: Image(
image: const AssetImage(
'assets/images/icon_direct_seeding_charm.png'),
gaplessPlayback: true,
height: 65.r),
),
],
),
),
],
),
showFocus() == true
? GestureDetector(
onTap: () {
addDeleteFriend(true,
'${widget.directUserDetailModel?.userId ?? 0}');
showFocusButton = false;
mySetState(() {});
},
child: Container(
height: 47,
width: 221,
margin:
const EdgeInsets.only(bottom: 20),
alignment: Alignment.center,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/bg_direct_focus.png'),
fit: BoxFit.fill, // 完全填充
)),
child: ContentTextBlod(
S.current.track,
16.0,
Colors.white,
FontWeight.w800)),
)
: Container(),
],
),
),
),
),
Positioned(
top: -39,
child: GestureDetector(
onTap: () {
MyRouter.pushMyMap(
context, MyRouter.friendFilesPage, {
'isContainer': false,
'userID':
'${widget.directUserDetailModel?.userId ?? 0}',
});
},
child: Avatar(
avatarUrl: '${getAvatar()}',
width: 78,
height: 78,
radius: 45,
isTap: false),
),
)
],
),
],
),
),
],
),
);
}
}
///显示用户详情信息,点击主播头像是1,其他是2
showDirectUserDetailDialog(context, int source,
{DirectUserDetailModel? directUserDetailModel, bool? hasFocusAnchor}) {
showModalBottomSheet(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24), topRight: Radius.circular(24))),
isScrollControlled: true,
enableDrag: false,
barrierColor: Colors.transparent,
backgroundColor: Colors.transparent,
context: context,
builder: (context) => DirectUserDetail(
directUserDetailModel: directUserDetailModel,
source: source,
hasFocusAnchor: hasFocusAnchor));
}
class DirectUserDetailModel {
int? userId;
String? avatar;
String? nickName;
int? sex;
int? age;
bool? isVip;
int? wealthLevel;
int? wealthValue;
int? charmLevel;
int? charmValue;
DirectUserDetailModel(
{this.userId,
this.avatar,
this.nickName,
this.sex,
this.age,
this.isVip,
this.wealthLevel,
this.wealthValue,
this.charmLevel,
this.charmValue});
}
简单来说关闭按钮Stack在Hi图标上,因为范围超出了,所以点击不了,那在外层加个蓝色的Container,关闭按钮Stack在蓝色的Container上
Stack(
children: [
Container(
alignment: Alignment.bottomLeft,
width: WidgetAdaptation.getWidth(60),
height: WidgetAdaptation.getWidth(60),
color: Colors.blue,
child: Container(
height: WidgetAdaptation.getWidth(50),
width: WidgetAdaptation.getWidth(50),
child: const Image(
image: AssetImage(
'assets/images/icon_conversation_say_hi.png'))),
),
Positioned(
top: 0,
right: 0,
child: Container(
child: Image(
image: const AssetImage(
'assets/images/icon_close_1@2x.png',
),
width: WidgetAdaptation.getWidth(18),
height: WidgetAdaptation.getWidth(18),
),
),
),
],
),
或者用下面这个方法:Stack的alignment: Alignment.bottomCenter,再加上蓝色弹窗设置margin:
EdgeInsets.only(bottom: WidgetAdaptation.getWidth(60)),关闭按钮叠在底部,自然就往下叠了
import 'dart:async';
import 'package:base_utils/base_utils.dart';
import 'package:base_utils/generated/l10n.dart';
import 'package:base_utils/utils/base/GlobalBase.dart';
import 'package:base_utils/utils/event_bus_util.dart';
import 'package:flutter/material.dart';
import '../../page/InAppWebView/InAppWebView.dart';
import '../router/routerUtil.dart';
///弹窗类型
enum DialogType {
TEXT,
IMAGE,
}
class VideoOperateDialog extends StatefulWidget {
OperateModel? model;
int dialogType; //dialogType:通知详细类型,1-音视频通话弹窗 2-直播间通话弹窗 3-应用全局弹窗
VideoOperateDialog({Key? key, this.model, required this.dialogType})
: super(key: key);
@override
State<StatefulWidget> createState() => VideoOperateDialogState();
}
class VideoOperateDialogState extends State<VideoOperateDialog> {
late StreamSubscription<VideoOperateEvent>? _operateEvent;
@override
void initState() {
super.initState();
if (widget.dialogType == 1) {
GlobalBase.liveVideoAllDialog.update('videoDialog', (value) => true);
} else if (widget.dialogType == 2) {
GlobalBase.liveVideoAllDialog.update('liveDialog', (value) => true);
} else if (widget.dialogType == 3) {
GlobalBase.liveVideoAllDialog.update('allDialog', (value) => true);
}
_operateEvent = BaseEventBus.listen((event) {
if (widget.model?.type == DialogType.TEXT) {
String? _message = event.message.messageData?.text;
if (_message != null && _message.isNotEmpty) {
if (_message != widget.model?.text) {
if (mounted) {
setState(() {
widget.model?.text = _message;
});
}
}
}
}
});
}
@override
void dispose() {
super.dispose();
if (widget.dialogType == 1) {
GlobalBase.liveVideoAllDialog.update('videoDialog', (value) => false);
} else if (widget.dialogType == 2) {
GlobalBase.liveVideoAllDialog.update('liveDialog', (value) => false);
} else if (widget.dialogType == 3) {
GlobalBase.liveVideoAllDialog.update('allDialog', (value) => false);
}
if (_operateEvent != null) {
_operateEvent?.cancel();
}
}
@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: widget.model?.type == DialogType.TEXT
? textContainer()
: imageContainer(),
);
}
Widget textContainer() {
return GestureDetector(
onTap: () {},
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: WidgetAdaptation.getWidth(161),
maxWidth: WidgetAdaptation.getWidth(300)),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14), color: Colors.white),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.only(
left: WidgetAdaptation.getWidth(15),
right: WidgetAdaptation.getWidth(15)),
margin: EdgeInsets.only(
top: WidgetAdaptation.getWidth(40),
bottom: WidgetAdaptation.getWidth(20)),
child: Text(
widget.model?.text ?? "",
textAlign: TextAlign.center,
style:
const TextStyle(color: Color(0xFF000000), fontSize: 16),
),
),
Container(
margin:
EdgeInsets.only(bottom: WidgetAdaptation.getWidth(10)),
child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: GestureDetector(
onTap: () {
RouterUtil.pop(context);
},
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.only(
top: WidgetAdaptation.getWidth(12),
bottom: WidgetAdaptation.getWidth(12)),
margin: EdgeInsets.only(
right: WidgetAdaptation.getWidth(15),
left: WidgetAdaptation.getWidth(15)),
decoration: BoxDecoration(
color: const Color(0xFF00D6CA),
borderRadius: BorderRadius.circular(50),
border: Border.all(
width: 1, color: const Color(0xFF00D6CA))),
child: Text(
S.current.btn_ok,
style: const TextStyle(
color: Colors.white, fontSize: 15),
),
),
),
)
],
),
)
],
),
),
),
),
);
}
Widget imageContainer() {
return Center(
child: Stack(
alignment: Alignment.center,
children: [
Container(
color: Colors.blue,
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.bottomCenter,
children: [
GestureDetector(
onTap: () {
//关闭页面后跳转webview
RouterUtil.pop(context);
if (widget.model?.jumpUrl != null &&
widget.model!.jumpUrl!.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
InAppWebViewPage(widget.model!.jumpUrl!)),
);
}
},
child: Container(
margin:
EdgeInsets.only(bottom: WidgetAdaptation.getWidth(60)),///!!!调这个即可
height: WidgetAdaptation.getWidth(320),
width: WidgetAdaptation.getWidth(240),
child: Image.network(
widget.model?.imageUrl ?? "",
fit: BoxFit.fill,
),
),
),
Visibility(
visible: widget.model?.showClose == true ? true : false,
child: Positioned(
child: GestureDetector(
onTap: () {
RouterUtil.pop(context);
},
child: Container(
padding: EdgeInsets.only(
right: WidgetAdaptation.getWidth(15),
top: 0,
left: WidgetAdaptation.getWidth(15)),
child: Image(
image: const AssetImage(
'assets/images/icon_close_circle.png'),
width: WidgetAdaptation.getWidth(30),
height: WidgetAdaptation.getWidth(30),
),
),
),
),
)
],
),
),
],
),
);
}
}
showVideoOperateDialog(context, OperateModel model, {required int dialogType}) {
showDialog(
context: context,
builder: (context) {
return VideoOperateDialog(model: model, dialogType: dialogType);
});
}
class OperateModel {
late DialogType type;
String? text;
String? imageUrl;
String? jumpUrl;
bool? showClose;
OperateModel(this.type,
{this.text, this.imageUrl, this.jumpUrl, this.showClose});
}