كيفية جلب البيانات من الجدول في فلاتر | how to get data from table in Flutter #3
في المقال السابق تعرفنا على كيفية إضافة البيانات في فلاتر وفي هذا المقال سوف نتعرف على كيفية الحصول على البيانات في عمليات الطباعة وهذة الخطوة من اهم الخطوات في إشاء الداتا بيز فهل يمكن اضافة بيانات وعدم الحصول عليها ؟ بالطبع لا يصلح اطلاقا ولذلك نحتاج الى اضافة وعرض للبيانات وهذا ما سنقوم به في هذة المقالة المميزة من دروس تعلم التعامل مع قواعد البيانات بتقنية flutter بسهوله وبطريقة مبسطه .
الشرح في flutter متوفر بشكل كبير في الفترة الاخيره ويوجد الكثير من أدوات الذكية التي تساعد على انجاز الاعمال بشكل اسرع مثال على ذلك plugin مفتوحة المصدر التي تسهل علينا الكثير و ال دروس التي نحصل على معلومات مختلفة منها تقوينا في المجال , واذا كنت في البرمجة بسيط او بمحنى اخر الصفر في البرمجة فلا تقلق فسوف نساعدك على تطوير من نفسك داخل المجال وهو ببساطة عبارة عن مجموعة من الاوامر التي نكتبها تخرج لنا تطبيق الجوال وكل شيئ سيكون بشرح مفصل بإذن الله , وسوف نحاول تقديم كورس الفلاتر بشكل مجاني لكم وذلك بعد ان انتهينا في الاندرويد و التطبيق عليها ويجب عليك تعلمها فهي الاساس او native واغلب الشركات تحتاج الى application native لذلك يجب عليك تعلم code خام الاول .
الفلاتر تعمل على widgets بمعنى ان كل حالة او عنصر نطلق عليه widgets في flutter و طريقة الكود هنا مختلفة عن الاندرويد قليلا لتعلم تصميم واجة تحتاج الى كتابتها عن طريق الاكواد وهذا افضل للمطورين واصبح android developer يفضلها مثل انشاء button بشكل اسرع وبالنسبة للتعامل مع firebase تقريبا نفس الفكرة التي يعملها بها مطور الاندرويد حيث يسمح للهاتف المحمول أيضا بالوصول الى ما يريد و الهواتف يجب ان توافق على الاتفاقية .
تخزين جميع الملاحظات داخل array خارجيه
قم بإنشاء ملف دارات جديد خارجي باسم constant او اي اسم ونقوم فقط بوضع List بالMap فقط لكي يتم تخزين البيانات داخلها واحضارها من الداخل .
ارجاع جميع البيانات من داخل الtable في فلاتر
نقوم بعمل دالة من نوع future والتي تستقبل بيانات مستقبليه بمعنى تستقبل بيانات تقوم انت بإداخلها وسوف نقوم بعمل استدعاء للdatabase بداخله ولا ننسى ان يكون نوعها Map لكي نحصل على كل المحتويات الموجوده بداخلها ونقوم بعمل async والتي تعني انتظر البيانات الى ان تصل بطريقة سلميه ثم قم بعرضها لنا , وارجع الى استدعاء قاعة البيانات وهي create database ونخبره بأن ينتهي من البيانات قم يقوم بعرضها لنا ويجعل الtasks وهي الlist تحتوي على محتويات الجدول الحاصل عليها ثم يطبعها لنا .
void create_db() async {
database = await openDatabase('note.db', version: 1,
onCreate: (database, version) {
print('DataBase is Created');
database
.execute(
'CREATE TABLE tasks(id INTEGER PRIMARY KEY, title TEXT , date TEXT , time TEXT , status TEXT)')
.then((value) {
print('Table Created');
}).catchError((error) {
print('Error ${error.toString()}');
});
}, onOpen: (database) {
getDataFromDB(database).then((value) {
setState(() {
tasks = value;
});
});
print('DataBase is Opened');
});
}
Future insert_database({
required String title,
required String time,
required String date,
}) async {
await database.transaction((txn) {
return txn
.rawInsert(
'INSERT INTO tasks(title , time , date , status) VALUES( "$title" , "$time" , "$date" , "active" )')
.then((value) {
print('done $value');
}).catchError((onError){
print('Error ${onError.toString()}');
});
});
}
Future<List<Map>> getDataFromDB(database) async
{
return await database!.rawQuery('SELECT * FROM tasks');
}
}
حل مشكلة اغلاق الBottomSheet عن طريق السحب
يوجد لدينا مشكلة بسيطة وهي عند تنزيل الBottomSheet الى الاسفل يتم اغلاقه لكن تبقى حالتها كما هي ولذلك سوف نتسخدم الامر .closed في نهايته والذين يعني اغلق الBottomSheet عندما ينتهي سواء كان الاغلاق عن طريق السحب للاسفل او كان عن طريق الضغط على زر اغلاق ويقوم بتغيير الحالة والايقونه
scaffoldKey.currentState!.showBottomSheet((context) => Padding(...),
elevation: 20.0,
// في حالة اغلاق الزر بأي شكل من الاشكال قم بتغيير الايقونه وغير حالة الزر
).closed.then((value) {
isBottomSheetShow = false;
setState(() {
iconDate = Icons.edit;
});
});
isBottomSheetShow = true;
setState(() {
iconDate = Icons.add;
});
}
},
child: Icon(iconDate),
),
كيفية اظهار Progress في حالة عدم وجود ملاحظات واخفاءه عندما يتم تحميل الملاحظات
سوف نقوم بعمل شرط بسيط وهو اذا كانت البيانات الموجوده في الlist تساوي الصفر اي لا يوجد بيانات اظهر ProgressIndicator واذا كانت هناك بيانات اظهرها لنا وبهذا سوف يقوم بإظهار الProgressIndicator اذا لم يكون هنا بيانات ويختفي عندما تصل البيانات وهذا الكود يكون بداخل الLayout .
body: tasks.length == 0 ? Center(child: CircularProgressIndicator()) : screen[currentIndex],
تصميم شكل لعرض البيانات من داخل table التي قمت بإضافتها في ملف componant.dart لاعادة استخدامه اكثر من مره .
الان نقوم بعمل تصميم للشكل الذي نريدة للبيانات ان تظهر به في الtable وهو عباره عن دائرة تحتوي على الساعه ومحتوى نصي بجانبها يكون الtitale واسفله محتوي نصي اخر يدل على التاريخ الذي قمنا بوضعه .
Widget buildTaskItem(Map model) => Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
children: [
CircleAvatar(
radius: 35,
child: Text('${model['time']}' , style: TextStyle(fontWeight: FontWeight.bold , fontSize: 15 , color: Colors.white),),
),
SizedBox(width: 20,),
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${model['title']}' , style: TextStyle(fontSize: 18,fontWeight: FontWeight.bold ) ,),
Text('${model['date']}' , style: TextStyle(color: Colors.grey , fontWeight: FontWeight.bold),),
],
),
],
),
);
عرض بيانات الnote داخل كلاس NewTask
الخطوة الاخيره وهيا اظهار البيانات بشكل صحيح واستدعائها ويكون داخل كلاس NewTask وهو الclass الذي يحوي البيانات والمفترض ان تظهر بداخله بشكل سليم .
class NewTask extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.separated(
itemBuilder: (context , value) => buildTaskItem(tasks[value]),
separatorBuilder: (context , value) => Padding(
padding: const EdgeInsetsDirectional.all(10),
child: Container(
width: double.infinity,
height: 1,
margin: EdgeInsetsDirectional.only(start: 20),
color: Colors.grey[300],
),
),
itemCount: tasks.length);
}
}