Problem: I have a flutter application that after loging in, i want to show a bottom sheet modal popup only when users of the app is not subscribed and restricts them from using the app and is clickable to take them straight to the subscription widget/page.
but i get an error saying "The argument type "Future" can't be assigned to the parameter type 'Widget'
Solution i tried:
I tried removing the Future and Async function i passed in the FloatingModal Class but it still gives same errors on runtime
i converted my stateless widget 'Dashboard' to stateful to see if it does the trick but it didn't work.
If this approach is completely wrong, what better approach would you recommend for me for the usecase/problem
Please note i am using the modal_bottom_sheet flutter package by Jaimeblasco. This app is also using a backend in laravel.
The 3 widget actively responsible are dashboard.dart
subscription_notice.dart
and floating_modal.dart
which i'll provide the code snippets.
Please i'll really need help as it's a project i'm working on at this time. Thank you :)
class Dashboard extends StatelessWidget {
const Dashboard({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
HomeController homeController = Get.find();
ServicesController servicesController = Get.find();
VerificationController verificationController = Get.find();
PlayersController playersController = Get.find();
var user =
UserModel.fromJson(jsonDecode(homeController.userData.value)).user!;
Widget content(context) {
return Obx(() => Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.only(
top: 40, left: 20, right: 20, bottom: 20),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.welcome
" ${user.firstName}",
style: const TextStyle(fontSize: 20)),
if (servicesController.subscription.isEmpty &&
!servicesController.loading &&
user.userType != "club_official")
FloatingModal(child: showFloatingModalBottomSheet(context: context, builder: (context) => const SubscriptionNotice())),
]);
),
const HorizontalAdvertBanner()
],
));
}
class SubscriptionNotice extends StatelessWidget {
const SubscriptionNotice({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
ServicesController servicesController = Get.find();
var user =
UserModel.fromJson(jsonDecode(servicesController.userData.value)).user!;
return Material(
child: SafeArea(
top: false,
child: Column(
children: [
const SizedBox(
height: 20,
),
CardItem(
icon: SvgPicture.asset("assets/images/warning_icon.svg"),
content: RichText(
text: TextSpan(
children: user.userType == "player"
? [
TextSpan(
text:
"you need to subscribe to a plan. Click on this ",
style: TextStyle(
fontSize: 14,
color: Get.isDarkMode
? AppColors.textLigth
: AppColors.textDark,
fontFamily: "Avenir")),
const TextSpan(
text: "link",
style: TextStyle(
color: Color(0xffFF9432),
fontSize: 14,
fontWeight: FontWeight.w600,
fontFamily: "Avenir")),
TextSpan(
text: " and subscribe now",
style: TextStyle(
fontSize: 14,
color: Get.isDarkMode
? AppColors.textLigth
: AppColors.textDark,
fontFamily: "Avenir"))
]
: [
TextSpan(
text:
" you need to subscribe. Click on this",
style: TextStyle(
fontSize: 14,
color: Get.isDarkMode
? AppColors.textLigth
: AppColors.textDark,
fontFamily: "Avenir")),
const TextSpan(
text: " link",
style: TextStyle(
color: Color(0xffFF9432),
fontSize: 14,
fontWeight: FontWeight.w600,
fontFamily: "Avenir")),
TextSpan(
text: ", and subscribe",
style: TextStyle(
fontSize: 14,
color: Get.isDarkMode
? AppColors.textLigth
: AppColors.textDark,
fontFamily: "Avenir"))
]),
),
onPressed: () {
TabRouting().pushScreen(context, const Services());
}),
],
),
),
);
}
}
class FloatingModal extends StatelessWidget {
final Widget child;
final Color? backgroundColor;
const FloatingModal({Key? key, required this.child, this.backgroundColor})
: super(key: key);
@override
Widget build(BuildContext context) {
return SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Material(
color: backgroundColor,
clipBehavior: Clip.antiAlias,
borderRadius: BorderRadius.circular(12),
child: child,
),
),
);
}
}
Future<T> showFloatingModalBottomSheet<T>({
required BuildContext context,
required WidgetBuilder builder,
Color? backgroundColor,
}) async {
final result = await showCustomModalBottomSheet(
context: context,
builder: builder,
containerWidget: (_, animation, child) => FloatingModal(
child: child,
),
expand: false);
return result;
}
CodePudding user response:
On your FloatingModal
it seeks a widget as a child. But showFloatingModalBottomSheet
is a future method.
You can use a tappable widget and on it tap event use this method.
FloatingModal(
child: ElevatedButton(
onPressed: () async {
showFloatingModalBottomSheet(context: context, builder: (context) => const SubscriptionNotice());
},
child: Text("showX"),
),
)
To show dialog directly after widget build on StatelessWidget
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
//condition if needed
await showFloatingModalBottomSheet(context: context, builder: (context) => const SubscriptionNotice());
});