Мы работаем над** приложением Flutter**, которое позволит пользователям планировать напоминание о лекарствах, чтобы они могли добавить название, дозировку и т. д., а также время, когда они хотят получать уведомления, поэтому мы попытались использовать потрясающий пакет уведомлений и внедрить его, но уведомления не приходят, что мы можем сделать? (для хранения данных мы использовали Firebase Firestore)
вот фрагмент кода для настройки уведомлений:
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fireproject/Medicine_log/models/medicine.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:fireproject/Medicine_log/models/medicine.dart';
// Notification service class for managing and scheduling notifications.
class NotificationService {
// Firestore instance for fetching medication data.
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
// Variable to keep track of notification IDs.
int _notificationId = 0;
// Constructor to initialize time zones for scheduling.
NotificationService() {
tz.initializeTimeZones();
}
// Method to handle events when a notification is created.
@pragma('vm:entry-point')
static Future onNotificationCreatedMethod(
ReceivedNotification receivedNotification) async {}
// Method to handle events when a notification is displayed.
@pragma('vm:entry-point')
static Future onNotificationsDisplayedMethod(
ReceivedNotification receivedNotification) async {}
// Method to handle events when a notification dismiss action is received.
@pragma('vm:entry-point')
static Future onDismissActionReceivedMethod(
ReceivedAction receivedAction) async {}
// Method to handle events when a user taps on a notification or action button.
@pragma('vm:entry-point')
static Future onActionReceiveMethod(
ReceivedAction receivedAction) async {}
// Method to schedule notifications based on the medicine data.
Future scheduleNotificationsBasedOnMedicine() async {
// Set the timezone location for scheduling.
final location = tz.getLocation('Asia/Amman');
// Fetch all medicines from Firestore.
QuerySnapshot querySnapshot = await _firestore.collection('medicine').get();
for (var doc in querySnapshot.docs) {
Medicine medicine = Medicine.fromFirestore(doc);
// Loop through each reminder time for the medicine.
for (var reminderTimestamp in medicine.reminderTime) {
DateTime utcScheduledTime = reminderTimestamp.toDate();
tz.TZDateTime scheduledTime =
tz.TZDateTime.from(utcScheduledTime, location);
// Schedule the notification.
await AwesomeNotifications().createNotification(
content: NotificationContent(
id: _notificationId++, // Incrementing ID for each notification.
channelKey: 'basic_channel',
title: 'Medicijne Herinnering', // Title for the notification.
body:
'${medicine.dosage} ${medicine.name} innemen.', // Body text for the notification.
),
schedule: NotificationCalendar.fromDate(
date: scheduledTime), // Scheduling details.
);
}
}
}
}
а это для страницы добавления напоминаний:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fireproject/notification/notification_serivce.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:intl/intl.dart';
import 'package:fireproject/Medicine_log/models/medicine.dart';
import 'package:fireproject/Medicine_log/widgets/time_input.dart';
import 'package:fireproject/Medicine_log/widgets/medication_card.dart';
import 'package:multi_select_flutter/multi_select_flutter.dart';
import '../widgets/date_selector.dart';
import '../widgets/footer.dart';
import '../widgets/input_style.dart';
import '../services/medication_service.dart';
import 'package:timezone/timezone.dart' as tz;
class medScreen extends StatefulWidget {
final Medicine? medicineToEdit;
const medScreen(
{super.key, this.medicineToEdit}); // Constructor for HomeScreen
@override
State createState() => _HomeScreenState();
}
// FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
// FlutterLocalNotificationsPlugin();
class _HomeScreenState extends State {
final GlobalKey _formKey =
GlobalKey(); // Form key for validation
final ValueNotifier selectedImageIndexNotifier = ValueNotifier(-1);
final List _allDays = [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
];
// List of image URLs for medication images
List imageUrls = [
'assets/images/—Pngtree—pharmacy drug health tablet pharmaceutical_6861618.png',
'assets/images/black-outlined-bottle.png',
'assets/images/black-outlined-pill.png',
'assets/images/blue-pill.png',
'assets/images/blue-yellow-tablet.png',
'assets/images/colored-bottle.png',
'assets/images/green-pill.png',
'assets/images/orange-tablet.png',
'assets/images/pink-pill.png',
'assets/images/pink-tablet.png',
'assets/images/white-tablet.png',
];
// Controllers for medication input fields
final TextEditingController _medicationNameController =
TextEditingController();
final TextEditingController _quantityController = TextEditingController();
final TextEditingController _doseController = TextEditingController();
List _selectedDays = []; // List to store selected days
List _reminderTimes = []; // List to store reminder times
String selectedImageUrl = ''; // Selected medication image URL
DateTime _selectedDate = DateTime.now(); // Selected date for medication
// Function to show the medication input form as a bottom sheet
void _showFormBottomSheet() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return _buildMedicationFormSheet(context);
},
);
}
// Future _initializeLocalNotifications() async {
// const AndroidInitializationSettings initializationSettingsAndroid =
// AndroidInitializationSettings('app_icon');
// final InitializationSettings initializationSettings =
// InitializationSettings(
// android: initializationSettingsAndroid,
// );
// await flutterLocalNotificationsPlugin.initialize(
// initializationSettings,
// );
// }
// Future _scheduleMedicationNotifications(
// List reminderTimes) async {
// for (var time in reminderTimes) {
// final dateTime = time.toDate();
// await flutterLocalNotificationsPlugin.zonedSchedule(
// 0,
// 'Medication Reminder',
// 'Time to take your medication',
// tz.TZDateTime.from(dateTime, tz.local),
// const NotificationDetails(
// android: AndroidNotificationDetails(
// 'your channel id',
// 'your channel name',
// importance: Importance.max,
// priority: Priority.high,
// ),
// ),
// androidAllowWhileIdle: true,
// uiLocalNotificationDateInterpretation:
// UILocalNotificationDateInterpretation.absoluteTime,
// );
// }
// }
// Function to update the reminder times
void _updateReminderTime(List times) {
setState(() {
_reminderTimes = times;
});
}
// Function to update the selected medication image URL
void _updateSelectedImageUrl(int index) {
setState(() {
selectedImageIndexNotifier.value = index;
selectedImageUrl = imageUrls[index];
});
}
// Function to handle date selection
void _onDateSelected(DateTime newDate) {
setState(() {
_selectedDate = newDate;
});
}
@override
void initState() {
// _initializeLocalNotifications();
super.initState();
if (widget.medicineToEdit != null) {
// If editing an existing medicine, populate input fields
_medicationNameController.text = widget.medicineToEdit!.name;
_quantityController.text = widget.medicineToEdit!.amount;
_doseController.text = widget.medicineToEdit!.dosage;
_selectedDays = widget.medicineToEdit!.days;
_reminderTimes = widget.medicineToEdit!.reminderTime;
selectedImageUrl = widget.medicineToEdit!.image;
// Trigger the bottom sheet to show after the build is complete
WidgetsBinding.instance.addPostFrameCallback((_) {
_showFormBottomSheet();
});
}
}
Future fetchReminderTimesFromFirestore() async {
List reminderTimes = [];
try {
// Reference to the 'medicine' collection in Firestore
CollectionReference medicineCollection =
FirebaseFirestore.instance.collection('medicine');
// Fetch documents from Firestore
QuerySnapshot querySnapshot = await medicineCollection.get();
// Iterate through each document in the collection
querySnapshot.docs.forEach((doc) {
// Extract reminder times from the document data
List reminderTimesData = doc['reminder_time'];
// Convert dynamic data to Timestamp objects
List reminderTimesForDocument = reminderTimesData
.map((timeData) => Timestamp.fromMillisecondsSinceEpoch(
timeData.seconds * 1000)) // Convert seconds to milliseconds
.toList();
// Add reminder times to the list
reminderTimes.addAll(reminderTimesForDocument);
});
} catch (e) {
print('Error fetching reminder times: $e');
// Return an empty list or handle the error as per your requirement
}
return reminderTimes;
}
// Function to build the medication input form as a bottom sheet
Widget _buildMedicationFormSheet(BuildContext context) {
return SizedBox(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 40),
child: Form(
key: _formKey,
child: Column(
children: [
// Header with back button and title
Row(
children: [
IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Color(0xffeb6081),
size: 20,
),
onPressed: () {
Navigator.pop(context);
},
constraints: const BoxConstraints(),
),
Expanded(
child: Container(
alignment: Alignment.centerLeft,
child: const Text(
'Schedule your medicine intake',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Color(0xffeb6081),
),
),
),
),
],
),
const SizedBox(height: 12),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Medicine name'),
const SizedBox(
height: 8,
),
// Input field for medication name
inputStyle(
prefixIcon: Icons.medication_rounded,
hintText: 'Ex. panadol',
controller: _medicationNameController,
)
],
),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Quantity'),
const SizedBox(height: 8),
// Input field for medication quantity
inputStyle(
prefixIcon: Icons.medical_information,
hintText: '1 pil/tablet',
controller: _quantityController)
],
),
),
const SizedBox(width: 20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Dosage'),
const SizedBox(
height: 8,
),
// Input field for medication dosage
inputStyle(
prefixIcon: Icons.my_library_add_rounded,
hintText: '500mg/ml',
controller: _doseController),
],
),
),
],
),
const SizedBox(height: 12),
// MultiSelect widget for selecting days
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MultiSelectBottomSheetField(
initialChildSize: 0.7,
maxChildSize: 0.95,
listType: MultiSelectListType.CHIP,
searchable: true,
buttonText: const Text('which days'), // Button text
title: const Text(
'select days to repeat'), // Title for the selection
items: _allDays
.map((day) => MultiSelectItem(day, day))
.toList(),
onConfirm: (values) {
// Callback when days are confirmed
setState(() {
_selectedDays = List.from(values);
});
},
chipDisplay: MultiSelectChipDisplay(
onTap: (value) {
setState(() {
_selectedDays.remove(value);
});
},
),
),
],
),
const SizedBox(height: 12),
// TimeInputWidget for selecting reminder times
TimeInputWidget(
onTimeChanged: _updateReminderTime,
),
const SizedBox(height: 12),
// Medication image selection
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Medicine type'), // Title for medication image
SizedBox(
height: 80,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: imageUrls.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_updateSelectedImageUrl(
index); // Update the selected image URL
},
child: ValueListenableBuilder(
valueListenable: selectedImageIndexNotifier,
builder: (context, selectedImageIndex, child) {
return Container(
width: 80,
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
),
decoration: BoxDecoration(
border: Border.all(
color: selectedImageIndex == index
? Colors
.blue // Border color when selected
: Colors
.transparent, // No border when not selected
width: 2.0, // Border width
),
),
transform: Matrix4.identity()
..scale(0.8), // Scale down the image
child: Column(
children: [
Expanded(
child: Image.asset(imageUrls[index]),
),
],
),
);
},
),
);
},
),
),
],
),
// Submit button for saving medication
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith(
(states) => const Color(0xffeb6081), // Button color
),
minimumSize: MaterialStateProperty.resolveWith(
(states) => Size(
MediaQuery.of(context).size.width * 0.95,
50.0,
),
),
),
onPressed: () async {
if (_formKey.currentState!.validate()) {
// Create or update a Medicine object
Medicine medicine = Medicine(
id: widget.medicineToEdit
?.id, // Use existing ID if in update mode
name: _medicationNameController.text,
dosage: _doseController.text,
image: selectedImageUrl,
days: _selectedDays,
reminderTime: _reminderTimes,
amount: _quantityController.text,
);
MedicationService medicationService =
MedicationService();
try {
if (widget.medicineToEdit == null) {
// Create mode: Save a new medicine
await medicationService.createMedicine(medicine);
if (kDebugMode) {
print('Medicine created successfully');
}
} else {
// Update mode: Update existing medicine
await medicationService.updateMedicine(medicine);
if (kDebugMode) {
print('Medicine updated successfully');
}
}
// Clear input fields and state variables
_medicationNameController.clear();
_doseController.clear();
_quantityController.clear();
_selectedDays.clear();
_reminderTimes.clear();
selectedImageUrl = '';
// _scheduleMedicationNotifications;
Navigator.of(context).pop(); // Close the bottom sheet
} catch (e) {
if (kDebugMode) {
print('Error processing medicine: $e');
}
}
}
},
child: const Text(
'ADD', // Button text
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: Colors.white),
),
),
),
],
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
// Format the selected date for display
String formattedDate =
DateFormat('d MMMM').format(_selectedDate); // Use _selectedDate
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
// Display the DateSelector widget
DateSelector(
formattedDate: formattedDate,
onDateSelected: _onDateSelected, // Set up the callback
),
// Display the MedicationCard widget and pass the selected date
MedicationCard(
selectedDate:
_selectedDate), // Pass the selected date to MedicationCard
],
),
),
bottomNavigationBar: Footer(
onButtonPressed: _showFormBottomSheet, // Show the medication input form
),
);
}
}
Подробнее здесь: https://stackoverflow.com/questions/784 ... ion-issues
Проблемы с уведомлениями Flutter ⇐ Android
Форум для тех, кто программирует под Android
1715207772
Anonymous
Мы работаем над** приложением Flutter**, которое позволит пользователям планировать напоминание о лекарствах, чтобы они могли добавить название, дозировку и т. д., а также время, когда они хотят получать уведомления, поэтому мы попытались использовать потрясающий пакет уведомлений и внедрить его, но уведомления не приходят, что мы можем сделать? (для хранения данных мы использовали Firebase Firestore)
вот фрагмент кода для настройки уведомлений:
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fireproject/Medicine_log/models/medicine.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:fireproject/Medicine_log/models/medicine.dart';
// Notification service class for managing and scheduling notifications.
class NotificationService {
// Firestore instance for fetching medication data.
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
// Variable to keep track of notification IDs.
int _notificationId = 0;
// Constructor to initialize time zones for scheduling.
NotificationService() {
tz.initializeTimeZones();
}
// Method to handle events when a notification is created.
@pragma('vm:entry-point')
static Future onNotificationCreatedMethod(
ReceivedNotification receivedNotification) async {}
// Method to handle events when a notification is displayed.
@pragma('vm:entry-point')
static Future onNotificationsDisplayedMethod(
ReceivedNotification receivedNotification) async {}
// Method to handle events when a notification dismiss action is received.
@pragma('vm:entry-point')
static Future onDismissActionReceivedMethod(
ReceivedAction receivedAction) async {}
// Method to handle events when a user taps on a notification or action button.
@pragma('vm:entry-point')
static Future onActionReceiveMethod(
ReceivedAction receivedAction) async {}
// Method to schedule notifications based on the medicine data.
Future scheduleNotificationsBasedOnMedicine() async {
// Set the timezone location for scheduling.
final location = tz.getLocation('Asia/Amman');
// Fetch all medicines from Firestore.
QuerySnapshot querySnapshot = await _firestore.collection('medicine').get();
for (var doc in querySnapshot.docs) {
Medicine medicine = Medicine.fromFirestore(doc);
// Loop through each reminder time for the medicine.
for (var reminderTimestamp in medicine.reminderTime) {
DateTime utcScheduledTime = reminderTimestamp.toDate();
tz.TZDateTime scheduledTime =
tz.TZDateTime.from(utcScheduledTime, location);
// Schedule the notification.
await AwesomeNotifications().createNotification(
content: NotificationContent(
id: _notificationId++, // Incrementing ID for each notification.
channelKey: 'basic_channel',
title: 'Medicijne Herinnering', // Title for the notification.
body:
'${medicine.dosage} ${medicine.name} innemen.', // Body text for the notification.
),
schedule: NotificationCalendar.fromDate(
date: scheduledTime), // Scheduling details.
);
}
}
}
}
а это для страницы добавления напоминаний:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fireproject/notification/notification_serivce.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:intl/intl.dart';
import 'package:fireproject/Medicine_log/models/medicine.dart';
import 'package:fireproject/Medicine_log/widgets/time_input.dart';
import 'package:fireproject/Medicine_log/widgets/medication_card.dart';
import 'package:multi_select_flutter/multi_select_flutter.dart';
import '../widgets/date_selector.dart';
import '../widgets/footer.dart';
import '../widgets/input_style.dart';
import '../services/medication_service.dart';
import 'package:timezone/timezone.dart' as tz;
class medScreen extends StatefulWidget {
final Medicine? medicineToEdit;
const medScreen(
{super.key, this.medicineToEdit}); // Constructor for HomeScreen
@override
State createState() => _HomeScreenState();
}
// FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
// FlutterLocalNotificationsPlugin();
class _HomeScreenState extends State {
final GlobalKey _formKey =
GlobalKey(); // Form key for validation
final ValueNotifier selectedImageIndexNotifier = ValueNotifier(-1);
final List _allDays = [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
];
// List of image URLs for medication images
List imageUrls = [
'assets/images/—Pngtree—pharmacy drug health tablet pharmaceutical_6861618.png',
'assets/images/black-outlined-bottle.png',
'assets/images/black-outlined-pill.png',
'assets/images/blue-pill.png',
'assets/images/blue-yellow-tablet.png',
'assets/images/colored-bottle.png',
'assets/images/green-pill.png',
'assets/images/orange-tablet.png',
'assets/images/pink-pill.png',
'assets/images/pink-tablet.png',
'assets/images/white-tablet.png',
];
// Controllers for medication input fields
final TextEditingController _medicationNameController =
TextEditingController();
final TextEditingController _quantityController = TextEditingController();
final TextEditingController _doseController = TextEditingController();
List _selectedDays = []; // List to store selected days
List _reminderTimes = []; // List to store reminder times
String selectedImageUrl = ''; // Selected medication image URL
DateTime _selectedDate = DateTime.now(); // Selected date for medication
// Function to show the medication input form as a bottom sheet
void _showFormBottomSheet() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return _buildMedicationFormSheet(context);
},
);
}
// Future _initializeLocalNotifications() async {
// const AndroidInitializationSettings initializationSettingsAndroid =
// AndroidInitializationSettings('app_icon');
// final InitializationSettings initializationSettings =
// InitializationSettings(
// android: initializationSettingsAndroid,
// );
// await flutterLocalNotificationsPlugin.initialize(
// initializationSettings,
// );
// }
// Future _scheduleMedicationNotifications(
// List reminderTimes) async {
// for (var time in reminderTimes) {
// final dateTime = time.toDate();
// await flutterLocalNotificationsPlugin.zonedSchedule(
// 0,
// 'Medication Reminder',
// 'Time to take your medication',
// tz.TZDateTime.from(dateTime, tz.local),
// const NotificationDetails(
// android: AndroidNotificationDetails(
// 'your channel id',
// 'your channel name',
// importance: Importance.max,
// priority: Priority.high,
// ),
// ),
// androidAllowWhileIdle: true,
// uiLocalNotificationDateInterpretation:
// UILocalNotificationDateInterpretation.absoluteTime,
// );
// }
// }
// Function to update the reminder times
void _updateReminderTime(List times) {
setState(() {
_reminderTimes = times;
});
}
// Function to update the selected medication image URL
void _updateSelectedImageUrl(int index) {
setState(() {
selectedImageIndexNotifier.value = index;
selectedImageUrl = imageUrls[index];
});
}
// Function to handle date selection
void _onDateSelected(DateTime newDate) {
setState(() {
_selectedDate = newDate;
});
}
@override
void initState() {
// _initializeLocalNotifications();
super.initState();
if (widget.medicineToEdit != null) {
// If editing an existing medicine, populate input fields
_medicationNameController.text = widget.medicineToEdit!.name;
_quantityController.text = widget.medicineToEdit!.amount;
_doseController.text = widget.medicineToEdit!.dosage;
_selectedDays = widget.medicineToEdit!.days;
_reminderTimes = widget.medicineToEdit!.reminderTime;
selectedImageUrl = widget.medicineToEdit!.image;
// Trigger the bottom sheet to show after the build is complete
WidgetsBinding.instance.addPostFrameCallback((_) {
_showFormBottomSheet();
});
}
}
Future fetchReminderTimesFromFirestore() async {
List reminderTimes = [];
try {
// Reference to the 'medicine' collection in Firestore
CollectionReference medicineCollection =
FirebaseFirestore.instance.collection('medicine');
// Fetch documents from Firestore
QuerySnapshot querySnapshot = await medicineCollection.get();
// Iterate through each document in the collection
querySnapshot.docs.forEach((doc) {
// Extract reminder times from the document data
List reminderTimesData = doc['reminder_time'];
// Convert dynamic data to Timestamp objects
List reminderTimesForDocument = reminderTimesData
.map((timeData) => Timestamp.fromMillisecondsSinceEpoch(
timeData.seconds * 1000)) // Convert seconds to milliseconds
.toList();
// Add reminder times to the list
reminderTimes.addAll(reminderTimesForDocument);
});
} catch (e) {
print('Error fetching reminder times: $e');
// Return an empty list or handle the error as per your requirement
}
return reminderTimes;
}
// Function to build the medication input form as a bottom sheet
Widget _buildMedicationFormSheet(BuildContext context) {
return SizedBox(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 40),
child: Form(
key: _formKey,
child: Column(
children: [
// Header with back button and title
Row(
children: [
IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Color(0xffeb6081),
size: 20,
),
onPressed: () {
Navigator.pop(context);
},
constraints: const BoxConstraints(),
),
Expanded(
child: Container(
alignment: Alignment.centerLeft,
child: const Text(
'Schedule your medicine intake',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Color(0xffeb6081),
),
),
),
),
],
),
const SizedBox(height: 12),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Medicine name'),
const SizedBox(
height: 8,
),
// Input field for medication name
inputStyle(
prefixIcon: Icons.medication_rounded,
hintText: 'Ex. panadol',
controller: _medicationNameController,
)
],
),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Quantity'),
const SizedBox(height: 8),
// Input field for medication quantity
inputStyle(
prefixIcon: Icons.medical_information,
hintText: '1 pil/tablet',
controller: _quantityController)
],
),
),
const SizedBox(width: 20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Dosage'),
const SizedBox(
height: 8,
),
// Input field for medication dosage
inputStyle(
prefixIcon: Icons.my_library_add_rounded,
hintText: '500mg/ml',
controller: _doseController),
],
),
),
],
),
const SizedBox(height: 12),
// MultiSelect widget for selecting days
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MultiSelectBottomSheetField(
initialChildSize: 0.7,
maxChildSize: 0.95,
listType: MultiSelectListType.CHIP,
searchable: true,
buttonText: const Text('which days'), // Button text
title: const Text(
'select days to repeat'), // Title for the selection
items: _allDays
.map((day) => MultiSelectItem(day, day))
.toList(),
onConfirm: (values) {
// Callback when days are confirmed
setState(() {
_selectedDays = List.from(values);
});
},
chipDisplay: MultiSelectChipDisplay(
onTap: (value) {
setState(() {
_selectedDays.remove(value);
});
},
),
),
],
),
const SizedBox(height: 12),
// TimeInputWidget for selecting reminder times
TimeInputWidget(
onTimeChanged: _updateReminderTime,
),
const SizedBox(height: 12),
// Medication image selection
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Medicine type'), // Title for medication image
SizedBox(
height: 80,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: imageUrls.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_updateSelectedImageUrl(
index); // Update the selected image URL
},
child: ValueListenableBuilder(
valueListenable: selectedImageIndexNotifier,
builder: (context, selectedImageIndex, child) {
return Container(
width: 80,
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
),
decoration: BoxDecoration(
border: Border.all(
color: selectedImageIndex == index
? Colors
.blue // Border color when selected
: Colors
.transparent, // No border when not selected
width: 2.0, // Border width
),
),
transform: Matrix4.identity()
..scale(0.8), // Scale down the image
child: Column(
children: [
Expanded(
child: Image.asset(imageUrls[index]),
),
],
),
);
},
),
);
},
),
),
],
),
// Submit button for saving medication
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith(
(states) => const Color(0xffeb6081), // Button color
),
minimumSize: MaterialStateProperty.resolveWith(
(states) => Size(
MediaQuery.of(context).size.width * 0.95,
50.0,
),
),
),
onPressed: () async {
if (_formKey.currentState!.validate()) {
// Create or update a Medicine object
Medicine medicine = Medicine(
id: widget.medicineToEdit
?.id, // Use existing ID if in update mode
name: _medicationNameController.text,
dosage: _doseController.text,
image: selectedImageUrl,
days: _selectedDays,
reminderTime: _reminderTimes,
amount: _quantityController.text,
);
MedicationService medicationService =
MedicationService();
try {
if (widget.medicineToEdit == null) {
// Create mode: Save a new medicine
await medicationService.createMedicine(medicine);
if (kDebugMode) {
print('Medicine created successfully');
}
} else {
// Update mode: Update existing medicine
await medicationService.updateMedicine(medicine);
if (kDebugMode) {
print('Medicine updated successfully');
}
}
// Clear input fields and state variables
_medicationNameController.clear();
_doseController.clear();
_quantityController.clear();
_selectedDays.clear();
_reminderTimes.clear();
selectedImageUrl = '';
// _scheduleMedicationNotifications;
Navigator.of(context).pop(); // Close the bottom sheet
} catch (e) {
if (kDebugMode) {
print('Error processing medicine: $e');
}
}
}
},
child: const Text(
'ADD', // Button text
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: Colors.white),
),
),
),
],
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
// Format the selected date for display
String formattedDate =
DateFormat('d MMMM').format(_selectedDate); // Use _selectedDate
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
// Display the DateSelector widget
DateSelector(
formattedDate: formattedDate,
onDateSelected: _onDateSelected, // Set up the callback
),
// Display the MedicationCard widget and pass the selected date
MedicationCard(
selectedDate:
_selectedDate), // Pass the selected date to MedicationCard
],
),
),
bottomNavigationBar: Footer(
onButtonPressed: _showFormBottomSheet, // Show the medication input form
),
);
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/78451443/flutter-notification-issues[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия