اذهب إلى المحتوى

Flutter Dev

الأعضاء
  • المساهمات

    787
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    2

أجوبة بواسطة Flutter Dev

  1. بتاريخ 10 دقائق مضت قال Wael Aljamal:

    عملية التهيئة تختبر قيمة المتغير هل هي null أم لا.

    وبذلك وضع late ليس سليم في هذه الحالة، أي يجب أن يكون نمط المتغير nullable

    
    Future? _getTaskAsync;

     

    كما أن هنالك ملاحظة، إسناد قيمة لدالة غير متزامنة يتوجب استخدام await قبل الاستدعاء

    
     _getTaskAsync = await ApiUser();

     

    مرحبا اخي

    ساقوم بتجربة ذلك

    الا يوجد حل لوضع تحقق من البيانات في future ؟

  2. تحيه طيبه للجميع 

    أقوم بعملية بجلب البيانات من السيرفر وعرضها من خلال FutureBuilder و ListView

    المشكلة انني في كل مره احضر البيانات احصل على الخطاء التالي:

    LateInitializationError: Field '_getTaskAsync@199262776' has not been initialized.

    وموقع الخطاء في future

    الكود المستعمل:

    class _HomePageState extends State<MyApp> {
    
      bool showicon=false;
      var ListDataPrefs;
      late Future _getTaskAsync;
      @override
      void initState() {
        Future.delayed(Duration.zero, () {
          _getTaskAsync=ApiUser();
        });
    
        super.initState();
      }
    
      Future ApiUser() async {
        setState(() {
          showicon = true;
        });
        final String url = '***************=';
        var response = await http.post(Uri.parse(url));
        var responsebody = jsonDecode(response.body);
    
        if (responsebody.length > 0) {
          return responsebody;
        } else {
          showicon = false;
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
    
            body:Center(child: Container(
    
            child: ListView(
              children: <Widget>[
              FutureBuilder(
                    future: _getTaskAsync,
                    builder: (context, AsyncSnapshot snapshot) {
                      if (snapshot.hasData) {
                        return ListView.builder(
                            physics: ScrollPhysics(),
                            scrollDirection: Axis.vertical,
                            shrinkWrap: true,
                            itemCount: snapshot.data.length,
                            itemBuilder: (context, index) {
                              return
                              Card(
                            
                                child: Container(
                                  padding: EdgeInsets.all(6),
                                  child: Row(
                                    children: <Widget>[
    
                                      Flexible(
                                        child: Column(
    
                                          children: <Widget>[
                                            MergeSemantics(
                                              child: Row(
                                                children: <Widget>[
                                                  Flexible(
                                                    child: Text(
                                                        "${snapshot.data[index]['name']}",
    
                                                    ),
                                                  )
                                                ],
                                              ),
                                            ),
    
    
                                          ],
                                        ),
                                      )
                                    ],
                                  ),
                                ),
                              );
                            }
                        );
    
                      } else if (snapshot.hasError) {
    
                        return Center(
                            child: Image.asset(
                              'assets/data.png',
                              fit: BoxFit.contain,
                              width: 180,
                              height: 180,
                            ));
    
                      }
    
    
                      return showicon? SizedBox(
                        height: MediaQuery.of(context).size.height / 1.3,
                        child: Center(
                          child: CircularProgressIndicator(
                            valueColor:
                            new AlwaysStoppedAnimation<Color>(Colors.black),
                          ),
                        ),
                      ):Text('');
                    }
    
    
    
                ),
    
    
              ],
            ),
            )
            )
       
       
        );
      }
    }
    
    

    هل توجد طريقة لتفادي هذا الخطاء او حله؟ مع العلم ان الكود يعمل ولكن تظهر صفحة حمراء  ورسالة الخطاء جزء من الثانية ثم تختفي ثم يظهر كود الخطاء بعدها

    • أعجبني 1
  3. بتاريخ 11 ساعات قال Wael Aljamal:

    أولاً جرب عدم تمرير itemCount له، إن لم تنجح..

    يوجد مكتبة مخصصة لهذه الحركة: carousel_slider تأكد من تمرير enableInfiniteScroll: true للباني

     

    يمكن تطبيق فكرة الدوران من خلال تمرير باقي القسمة لمكان دليل الصفحة المراد عرضها، وبذلك تصبح حلقة لانهائية (مثال) حيث أن باقي القسمة على 3  للمتغير i في حال أخذ هذا المتغير مجال من الاعداد سيكون دوري

    
    for i 1:100
    
    i % 3 => 0 1 2 0 1 2 0 1 2 0 1 2..

    لذلك،

    لمنع الانتقال يمكن عمل حل ذكي نسبياً وهو تكرار المصفوفة الأصلية بشكل معكوس (دمج قائمة الصفحات مع عكسها عدة مرات)

    
    pages =   [1,2,3,4]
    reverse = [3,2]  // بدون الأول لمنع التكرار
    
    myList =  pages   + reverse 
           = 1 2 3 4     3 2 
           
    
    final_list = myList + myList + myList ..
    
    = 1 2 3 4 3 2 1 2 3 4 3 2 1 2 3 4 3 2 1 2 3 4 3 2 

    مرر الدليل الحالي  على عدد الصفحات ل itemBuilder حيث أن الصفحات موضوعة ضمن مصفوفة باسم childern_ في المثال (final_list)

    
    return PageView.builder(
      itemBuilder: (context, index) {
        return _children[index % _children.length];
      },
      controller: pageController,
    );

    الآن سوف يتم التمرير بشكل دائري.

    اهلا اخي الكريم

    نعم انا استعمل المكتبة التي قمت بالإشارة لها انت ولكن حقيقه الي فتره أحاول اقلل استعمال المكاتب والانتقال الى الأدوات التي تمنحها فلاتر لكثير من الأسباب أولها واهمها توقف المطورين فجاه عن تطوير المكتبة مما يجعلك مجبور على البحث عن حل مختلف 

    والنقطة الثانية المكاتب اغلب الأوقات لا تتوافق مع إصدارات فلاتر الحديثة فتره من الزمن حتى يقوم المطور بتحديثها + تحتاج تحديثات وتغيرات بشكل مستمر ما يشكل مشكله مع الانتقال من اصدار فلاتر قديم الى اصدار احدث وهيا عدم التوافق

     

    حقيقه لا اعلم اذا كان تفكيري صحيح وانتم اهل الخبرة في هذا الامر ياليت تبدي رايك على هذا النقاط 

  4. تحيه طيبه للجميع

    لدي استفسار لو تكرمتم

    هل توجد طريقة لعمل Pageview  يتحرك بشكل دائري مستمر؟ بمعنى الان لو قمت بتحريكه سوف يذهب الى اخر صوره ومن ثم انا مجبور الرجوع للخلف ان ارغب ان اجعله يتحرك بشكل مستمر لما يوصل الى اخر صوره استطيع اكمل دائرتي تحركي والذهب الى الصورة الأولى حصلت على طريقة وهيا لما يكون في اخر صوره يعمل قفزة الى الصفحة الأولى ولكن الشكل ليس جيد لنه لا يتحرك بشكل دائري انما يعود للخلف مثل شريط الفيلم الذي يتم اعادته للخلف

     

    هل توجد طريقة لتحريكه بشكل دائري بدون ان يصل الى حد نهائي؟

    • أعجبني 1
  5. بتاريخ الآن قال Wael Aljamal:

    طيب متى تريد تنفيذ الدالة

    ارغب بوضعها في دالة مختلفة وسوف أقوم بتحقق من تلك الدالة لو كانت فارغة سوف تعمل هذا الدالة ولكن المشكلة الان هيا تعمل كذا او كذا تعمل في كل الحالات حتى الجملة الشرطية لا تنفع معها 

  6. بتاريخ 23 دقائق مضت قال Wael Aljamal:

    getdataCat تعيد قائمة إن كانت قائمة أغراض برمجية، أي العنصر فيه عدة قيم سوف تكون قائمة من dynamic لأذلك نعدل نمط إرجاع الدالة

    
    
    Future<<List<dynamic>> getdataCat()..
      
      Future.value(responsebody);
    

    وإذا كانت تعيد سلاسل نصية؟

    نوع القيمة المعادة يجب أن يكون نفسه من نمط ما تحسبه و تعيده الدالة.

    
    Future<<List<String>> getdataCat()..
      
      Future.value(responsebody);

    أي ما يعيده jsonDecode إن كان كما قلت فسوف نعيد تعديل نمطه من dynamic إلى string

    
    jsonDecode(responsebody).cast<List<String>();

     

    المشكلة اخي الكريم ليس في نوع البيانات المعادة قمت بتجربة كل ما ذكرته انت الدالة تعمل بشكل جيد ولكن الخطاء يظهر مع كلمة future: في FutureBuilder بنفس لما أقوم بإزالة الاقواس يظهر خط احمر اسفل اسم الدالة

  7. بتاريخ 2 دقائق مضت قال Wael Aljamal:

    سبب الشكلة هو نمط الإعادة للدالة getdataCat حاول عملها أن تعيد  كالتالي:

    
    if (responsebody.length >0){
          return Future.value(responsebody);
        }

     

    لم ينجح الامر اخي بعدها تظهر خطاء اعتذر على ذلك

  8. بتاريخ 2 دقائق مضت قال Wael Aljamal:

    أرجو تمرير الدالة بالاسم فقط، وليس تنفيذها 

    
    future: getdataCat(),
                     ^^^
    =>
    
    future: getdataCat,

    حيث أن هذا ما يسبب التنفيذ المباشر

    لما اعمل كذا احصل على الخطاء التالي اخي:

    The argument type 'Future<dynamic> Function()' can't be assigned to the parameter type 'Future<dynamic>?'.

     

     

  9. تحيه طيبه للجميع

    لدي استفسار لو تكرمتم 

    لماذا list view  لدى استعمالها مع Future Builder تعمل بدون ان اضع الدالة في initState()؟

    وهل يوجد حل حتى اجعلها تعمل فقط لو قمت بوضعها في initState()؟

     

    مثل الصفحة التالية:

    
    
    
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
    
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
    
    
    
    
      @override
      void initState() {
    
    
        super.initState();
      }
    
      bool showicon=false;
      var apiURL;
      Future getdataCat() async {
        setState(() {
          showicon=true;
        });
        apiURL = '***********************';
        var response = await http.post(Uri.parse(apiURL));
        var responsebody = jsonDecode(response.body);
        if (responsebody.length >0){
          return responsebody;
        }else{
          showicon=false;
    
        }
      }
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Flexible(
                  child: FutureBuilder(
                    future: getdataCat(),
                    builder: (context, AsyncSnapshot snapshot) {
                      if (!snapshot.hasData) {
                        // still waiting for data to come
                        return showicon
                            ? Center(
                            child: CircularProgressIndicator(
                              color: Colors.black,
    
                            ))
                            : SizedBox(
                            height: MediaQuery.of(context).size.height / 1.3,
                            child: Center(
                                child: Image.asset(
                                  'assets/data.png',
                                  fit: BoxFit.contain,
                                  width: 180,
                                  height: 180,
                                )));
                      } else if (snapshot.hasData &&
                          snapshot.data.isEmpty &&
                          snapshot.data <= 0) {
                        // got data from snapshot but it is empty
    
                        return SizedBox(
                            height: MediaQuery.of(context).size.height / 1.3,
                            child: Center(
                                child: Image.asset(
                                  'assets/data.png',
                                  fit: BoxFit.contain,
                                  width: 180,
                                  height: 180,
                                )));
                      } else {
                        // got data and it is not empty
                        return
    
                          GridView.builder(
                            physics: ScrollPhysics(),
                            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                                crossAxisCount: 2,
                                childAspectRatio: 3.4),
                            itemCount: snapshot.data.length,
                            itemBuilder: (context, index) {
                              return Container(
                                child: Card(
                                  child: Column(
                                    crossAxisAlignment:
                                    CrossAxisAlignment.stretch,
                                    children: <Widget>[
                                      Flexible(
                                          child: GestureDetector(
                                            child: Column(
                                                crossAxisAlignment:
                                                CrossAxisAlignment.stretch,
                                                children: <Widget>[
                                                  Flexible(
                                                    child: CachedNetworkImage(
                                                      imageUrl:
                                                      "${snapshot
                                                          .data[index]['image']}",
                                                      height: 180,
                                                      fit: BoxFit.cover,
                                                      errorWidget:
                                                          (context, url, error) =>
                                                          Icon(Icons.error),
                                                    ),
                                                  ),
                                                  Center(
                                                    child: Text(
                                                        "${snapshot
                                                            .data[index]['name']}"
                                                    )
                                                  )
                                                ]),
                                         
                                           
                                          )),
                                    ],
                                  ),
                                ),
                              );
                                  
                            },
                          );
    
                      }
                    },
                  ),
                )
    
              ],
            ),
          ),
    
        );
      }
    }

     

  10. تحيه طيبه للجميع 

    أقوم بجلب قائمة من قاعدة البيانات من خلال الكود التالي:

      var listCat = [];
      Future getdata() async {
        apiURL = '***************.php';
        var response = await http.post(Uri.parse(apiURL));
        var responsebody = jsonDecode(response.body);
        if (responsebody.length >0){
          for (int i = 0; i < responsebody.length; i++) {
            listCat.add(responsebody[i]['name']+ ':' + responsebody[i]['image'].toString());
          }
          return responsebody;
        }else{
      
    
        }
      }

    طبعا مثل ما هو واضح في الكود أعلاه انا أحاول الحصول على الاسم والصورة وهذا الامر لا توجد فيه مشكله  المشكلة الان انني ارغب بتخزين هذا listCat  في SharedPreferences  حتى استدعيها من جميع صفحات التطبيق

    لدي الكلاس التالي لحفظ SharedPreferences 

    class APIPreferences {
      static SharedPreferences ? _preferences;
      static const _keyMuinCat = 'MuinCat';
    
    
    
      static Future init() async => _preferences = await SharedPreferences.getInstance();
    
    
      static Future setMuinCat(String MuinCat) async => await _preferences!.setString(_keyMuinCat, MuinCat);
    
    
    
      static String? getMuinCat() => _preferences!.getString(_keyMuinCat);
    
    
    
    }

     

     

    ثم أقوم بحفظ ما احتاج الى حفظه من خلال السطر التالي من أي صفحة ارغب بذلك:

      APIPreferences.setMuinCat(listCat.toString());

    ثم يمكنني استدعاء البيانات التي تم تخزينها مسبقاً من أي موقع احتاجه فيها من خلال الكود التالي:

     CatList = APIPreferences.getMuinCat() ?? '';

     

    حاولت القيام بالامر التالي الان لحفظ القائمة في اول كود اعلاه:

      var listCat = [];
      Future getdata() async {
        apiURL = '***************.php';
        var response = await http.post(Uri.parse(apiURL));
    
        var responsebody = jsonDecode(response.body);
    
        if (responsebody.length >0){
    
          for (int i = 0; i < responsebody.length; i++) {
            listCat.add(responsebody[i]['name']+ ':' + responsebody[i]['image'].toString());
            APIPreferences.setMuinCat(listCat.toString());
    
          }
    
          return responsebody;
        }else{
    
    
        }
      }

    ولكن الامر لم ينجح لا اعلم حقيقه طريقة التعامل مع مثل هذا الامر لم يسبق ان تعاملت مع حفظ القوائم 

    كيف استطيع حفظها ثم استدعيها بشكل الصحيح حتى استطيع استعملها من خلال ListView

    ياليت من يعلم الطريقة الصحيحة يساعدنا ولكم جزيل الشكر

    • أعجبني 1
  11. بتاريخ 10 دقائق مضت قال Wael Aljamal:

    نعم يمكن ذلك، في بداية استعراض splash screen يمكنك عمل HTTP Get request من API لديك، وتخزن البيانات في متغيرات، ثم تعيد تمريرها من خلال باني الصفحة الرئيسية، الموضوع مرتبط بتطبيقك.

    Listview.builder لاتقوم بإنشاء عناصر القائمة إلا عند ظهورهم لواجهة التطبيق (مجال مرئي للمستخدم) وبذلك يكون التحميل بطيء.

    تأكد أن حجم الصور صغير و ليس كبير جداً، لأنه يؤثر في سرعة الانترنت + سرعة معالجة الهاتف

    مرحبا اخي

    بالنسبه الى اول نقطه اخي هل يوجد شرح عليها؟ حتى افهم الفكره

     

     

    اما بالنسبه الى موضوع listview.builder هل يمكن استبدلها بادوات مختلفه لحل المشكله؟

  12. تحيه طيبه للجميع

    ارغب بتسريع التطبيق قليلا وقد جاتني فكره لتحميل البيانات مسبقا للمستخدم من وقت دخوله ليكون تحميل البيانات اسرع / بمعنى لو لدي تطبيق مكون من 3 صفحات

    Login

    splash

    Main home

    ارغب بتحميل بيانات صفحة Main home قبل وصول المستخدم لها على سبيل المثال في وقت دخوله لصفحة splash سيتم تحميل بيانات صفحة Main home وفي وقت دخول المستخدم ستكون البيانات تم تحميلها وكانها ملحقات في التطبيق

     

    طبعا البيانات تاتي من قاعدة MySQL من خلال اتصال ملفات PHP ويتم عرضها في Listview.builder 

    نوع البيانات نصوص + صور

     

    ما هيا افضل طريقة لفعل ذلك؟ حقيقه لم اجد فكره مناسبه ام ان ذلك غير ممكن تطبيقه؟ 

     

    • أعجبني 1
  13. بتاريخ الآن قال Wael Aljamal:

    حاول إعطاء الزر تنسيق يلغي splashFactory

    
      style: ElevatedButton.styleFrom(
        splashFactory: NoSplash.splashFactory,
      ),

    أو ألوان شفافة لكل من unselectedIconTheme - selectedIconTheme

    
    bottomNavigationBar: BottomNavigationBar(
                  selectedIconTheme: IconThemeData(color: Colors.yellow),
                  unselectedIconTheme:  IconThemeData(color: Colors.white),

     

    اهلا اخي الكريم 

    نعم اعذرني تأخرت في الرد كنت أقوم بعملية التطبيق قمت بعمل ذلك وضع ثيم لزر ومن خلاله اصبح شفاف والغي تاثير

    • أعجبني 1
  14. بتاريخ 36 دقائق مضت قال Wael Aljamal:

    ما رأيك في وضع مكون نصي Text أو أي مكون النقر عليه لا يعمل تأثيرات بدل الزر Button، عن طريق وضع شرط ضمن Tree widget 

    أو تنسيق عرض الزر بأحد الأشكال التالية لمنع تأثير النقر عليها

    
    1-
    splashColor: Colors.transparent,  
      highlightColor: Colors.transparent,
    
    2-
    TextButton(
      style: ButtonStyle(
        overlayColor: MaterialStateProperty.all(Colors.transparent)
      )
    )
    
    3-
    style: TextButton.styleFrom(
      splashFactory: NoSplash.splashFactory,
    ),

     

     

    خلاص اخي تم ايجاد الحل جزاك الله الف خير قمت بتطبيق الثيم على الازار كافة وتم الغاء التاثير

  15. بتاريخ 17 ساعات قال Wael Aljamal:

    كما لديك، إن افترضنا وجود قائمة أزرار من BottomNavigationBarItem يمكننا تتبع الزر المحدد من خلال تخصيص متغير حالة يحمل ترقيمه index

    
    bottomNavigationBar: BottomNavigationBar(
      items: [
        BottomNavigationBarItem(
          ...
        ),
        BottomNavigationBarItem(
          ...
        ),
        BottomNavigationBarItem(
          ...
        ),
      ],
      onTap: navigationTapped,
      currentIndex: _page,
    ),

    ولنفرض أن اسمه page_ أو أي شيء مناسب.

    وعند النقر على الأزرار نحول الاستجابة لدالة مخصصة callback وهي فرضاُ navigationTapped

    سوف تستقبل هذه الدالة رقم الزر المضغوط عليه، و قارنه مع متغير الحالة لديك أو مع قيمة غير مرغوبة، ثم قم بالتصرف المناسب

    
    void navigationTapped(int page) {
      if (page == 2) {
        return;
      } else {
        setState(() {
          _selectedIndex = page;
        });
      }
    }

    لاحظ إن كان قد تم نقر الزر 2 لن نعمل تغيير في اختيار الواجهة

    كما يمكنك عمل ثيم مخصص مثلاً لون شفاف

    
    Theme(
      data: Theme.of(context).copyWith(
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
      ),
      child: YourWidget(),
    );

    كما يمكنك وضعه ضمن حاوية Container مع أبعاد  0 * 0 أو fontSize = 0

    جزاك الله الف خير اخي الكريم الطريقة فعاله 100%

    استفسار بسيط بس اخي الكريم انا عملت الحل الأول طبعا لنه ما ينفع أقوم بتطبيق الثيم عشان ما يختفي الاسم لني ارغب بعرضه والان الزر لا يعمل ولكن تأثير النقر يظهر هل توجد حتى الغي تأثير النقر ؟ بمعنى تظهر مثل الظل الأسود الشفاف لو قام المستخدم بضغط عليه

    • أعجبني 1
  16. تحيه طيبه للجميع 

    أقوم باستعمال  BottomNavigationBar لتنقل بين عدد من الصفحات المختلفة ولكني احتاج الى تعطيل زر قمت بوضعه ك نص في المنتصف 

    التصميم كالتالي:

    Screenshot_1658696622.thumb.png.1073577c130a5fc54e118cb4ee86682d.png

     

     

    احتاج الى إيقاف عمل الزر الذي في الأسفل والذي هو تحت اسم setting بمعنى لو قام المستخدم بضغط عليه لن يحدث أي تأثير حتى تأثير الظل لا يحدث حتى اجبر المستخدم على التوجه الى الزر الذي أعلاه بلون الأزرق.

    هل توجد طريقة لفعل ذلك؟

    الكود المستعمل كالتالي:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyHomePage());
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key}) : super(key: key);
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
    
      int index = 0;
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            home:
    
    
            Scaffold(
              body: _getBody(index),
              floatingActionButton: FloatingActionButton(
                onPressed: (){
                  print('sd');
                },
                child: Icon(Icons.add),
              ),
              bottomNavigationBar: BottomAppBar(
                shape: CircularNotchedRectangle(),
                color: Colors.red,
                notchMargin: 4,
                clipBehavior: Clip.antiAlias,
                child: BottomNavigationBar(
                    onTap: (value) => setState(() => index = value),
                    type: BottomNavigationBarType.fixed,items: [
    
                  BottomNavigationBarItem(icon: Icon(Icons.star), label:("Home")),
                  BottomNavigationBarItem(icon: Icon(Icons.star),  label:("me")),
                  BottomNavigationBarItem(icon: Icon(Icons.add),  label:("stting")),
                  BottomNavigationBarItem(icon: Icon(Icons.star),  label:("all")),
                  BottomNavigationBarItem(icon: Icon(Icons.star),  label:("you")),
                ]),
              ),
              floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
            ));
      }
      Widget _getBody(int index) {
        switch (index) {
          case 0:
    
            return Center(child: Text("1"),); 
          case 1:
            return Center(child: Text("2"),); 
          case 2:
            return Center(child: Text("3"),);
          case 3:
            return Center(child: Text("4"),);
          case 5:
            return Center(child: Text("5"),);
        }
    
        return Center(child: Text(""),);
      }
    }
    
    

     

    • أعجبني 1
  17. بتاريخ 31 دقائق مضت قال Wael Aljamal:

    إن الطلبية تعيد الوقت بشكل سلسلة نصية، بتنسيق الوقت كما هو مخزن في قاعدة البيانات لديك.

    لذلك على السيرفر أن يحول الوقت من تنسيق التاريخ لرقم عدد صحيح.

    • استخدم الدالة strtotime لتحويل الخانة التي تحمل الوقت لرقم
    
    echo strtotime('2012-03-27 18:47:00'); //--> which results to 1332866820

    أعتقد هكذا: ضمن الحلقة

    
    $row['TimeNow'] = strtotime($row['TimeNow']);
    $array[] = $row;

    ثم في Dart استقبل (الرقم) الذي سيكون على شكل نص (احتمال) وحوله لرقم صحيح

    
    import 'dart:convert';
    .
    .
    .
    
    
    
    TimeNowAge = int.parse(data[0]['TimeNow']);

     

    مرحبا اخي الكريم اصبح يعمل الكود بشكل التالي مع وجود مشكله بسيطة لم افهم سببها :

     Future<String?> GatData() async {
        setState(() {
          _isLoading = true;
        });
        var response = await http.get(
            Uri.parse("************.php"),
            headers: {"Accept": "application/json"});
    
        var convertDataToJson = json.decode(response.body);
        data = convertDataToJson['result'];
    setState(() {
      //TimeNowAge = int.parse(data[0]['TimeNow']);
      TimeNowAge = data[0]['TimeNow'];
      _isLoading=false;
      print(TimeNowAge);
    });
    
      }
    <?php
    require_once 'cnt.php';
    
    
    
    $sql="SELECT * FROM testtable ";
    
    $stmt = $con->prepare($sql); 
    
    
    $stmt->execute();
    
    $result = $stmt->get_result();
    
    
    
    
    $array = array();
    
    while ($row  = mysqli_fetch_assoc($result))
    {
        $row['TimeNow'] = strtotime($row['TimeNow']);
    
    	$array[] = $row;
    }
    
    
    echo ($result) ?
    json_encode(array("code" => 1, "result"=>$array)) :
    json_encode(array("code" => 0, "message"=>"Data not found !"));
    
    
    ?>

     

     

    المشكلة كالتالي:

    اول نقطة مفترض ان تظهر لي كتابه مع الوقت الذي يظهر حسب كود الوقت الذي فعلته في الأعلى على سبيل المثال 1Minutes ago ولكن الكود لدي لا يظهر أي شيء 

    المشكلة الثانية انا قمت بتخزين القيم التأليه في قاعدة البيانات :

    62d5a3b32ab56_Screenshot2022-07-18221645.png.7b1c5c7369bd8d20b2123b3264db683c.png

     

    ولكن ما يظهر لي مختلف كالتالي:

    Screenshot_1658168258.thumb.png.ceb75440ebb155bb23487f43b0a0b3c0.png

     

    مع العلم ان وقت المحاكي مضبوط + التاريخ ايضا 

  18. تحيه طيبه للجميع 

    وجدت شرح على الانترنت كيفية جلب الوقت الفعلي الذي تم تخزينه مع البوست في قاعدة البيانات والعمل كان كالتالي:

    كود الوقت:

    
    
    import 'package:intl/intl.dart';
    
    class TimeAgo{
    
      static String ? timeAgoSincDate(int time)
    
      {
    
        DateTime notificationDate =DateTime.fromMillisecondsSinceEpoch(time);
        final date2=DateTime.now();
        final diff =date2.difference(notificationDate);
        if(diff.inDays>8)
          return DateFormat("dd-MM-yyyy HH:mm:ss").format(notificationDate);
        else if ((diff.inDays/7).floor()>=1)
          return 'Last Week';
        else if (diff.inDays>=2)
          return '${diff.inDays}days ago';
        else if (diff.inDays>=1)
          return '1 daya ago';
        else if (diff.inHours>=2)
          return '${diff.inHours} hours ago';
    
        else if (diff.inHours>=1)
          return '${diff.inHours} 1 hours ago';
    
        else if (diff.inMinutes>=2)
          return '${diff.inMinutes} Minutes ago';
    
        else if (diff.inMinutes>=1)
          return '${diff.inMinutes} 1 Minutes ago';
        else if (diff.inSeconds>=3)
          return '${diff.inSeconds} Seconds ago';
    else
      return 'Just now';
      }
    
    }

     

    صفحة الاستعلام كالتالي:

    import 'dart:convert';
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'date_time_extension.dart';
    void main() {
      runApp(TimeAge());
    }
    class TimeAge extends StatefulWidget {
      const TimeAge({Key? key}) : super(key: key);
    
      @override
      _TimeAgeState createState() => _TimeAgeState();
    }
    
    class _TimeAgeState extends State<TimeAge> {
      @override
      void initState() {
        super.initState();
        GatData();
      }
    bool _isLoading =false;
    List data =[];
    var TimeNowAge;
      Future<String?> GatData() async {
        setState(() {
          _isLoading = true;
        });
        var response = await http.get(
            Uri.parse("**************/*********.php"),
            headers: {"Accept": "application/json"});
    
        var convertDataToJson = json.decode(response.body);
        data = convertDataToJson['result'];
    setState(() {
      TimeNowAge = data[0]['TimeNow'];
      _isLoading=false;
      print(TimeNowAge);
    });
    
      }
    
    
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(home: Scaffold(
          body: Column(children: [
    
            _isLoading ? CircularProgressIndicator():
    
    Text('${TimeAgo.timeAgoSincDate(TimeNowAge).toString()}')
          ]),
        ),);
      }
    }

    في الصفحة أعلاه انا أحاول جلب الوقت الذي قمت بتخزينه مسبقا في قاعدة البيانات ثم تحويله من خلال الكود الذي ارفقته في الأعلى

    ولكن احصل على الخطاء التالي كل ما حاولت تشغيل الكود:

    The following _TypeError was thrown building TimeAge(dirty, state: _TimeAgeState#d2e8c):
    type 'String' is not a subtype of type 'int'

    هل يوجد خطاء في طريقتي ؟ ما هو العمل الصحيح لتشغيل الكود ؟

    صفحة php كالتالي:

    <?php
    require_once 'cnt.php';
    
    
    
    $sql="SELECT * FROM testtable ";
    
    $stmt = $con->prepare($sql); 
    
    $stmt->execute();
    
    $result = $stmt->get_result();
    
    
    
    
    $array = array();
    
    while ($row  = mysqli_fetch_assoc($result))
    {
    	$array[] = $row;
    }
    
    
    echo ($result) ?
    json_encode(array("code" => 1, "result"=>$array)) :
    json_encode(array("code" => 0, "message"=>"Data not found !"));
    
    
    ?>

     

     

    والجدول في قاعدة البيانات كالتالي:

    62d59786f2fa3_Screenshot2022-07-18212504.thumb.png.e57b486f89babdccfa1a61df3715d6a9.png

     

    62d597af3347d_Screenshot2022-07-18212554.png.62ef3ca78fd99d0f6a0b3849a482b5ee.png

     

     

     

     

     

    • أعجبني 1
  19. بتاريخ 3 دقائق مضت قال Wael Aljamal:

    من الأفضل ذكر الغرض من الاستعلام بشكل عام ليصبح من السهل التفكير السليم بأفضل طريقة لجلب البيانات.

    دمج جدول مع نفسه هو عملية نقوم بها عند وجود علاقة بين كينونات (أسطر) نفس الجدول، مثل تصنيفات جزئية لتصنيفات رئيسية أو علاقة المدير مع موظفيه (رقم المدير يكون مفتاح في حقل رقم الموظف) بشكل آخر لكل موظف مدير.. علاقة متعدية.

    كما ترى، أنت تبحث عن تساوي خاصيتين من نسختين من الجدول لقيمة واحدة

    
    FeaturesBook AS A ON A.t1 = BookSpecifications.IDBookSpecifications 
                         ^^^^
    FeaturesBook AS B ON B.t2 = BookSpecifications.IDBookSpecifications 
                         ^^^^                       ^^^^^^^^^^^^^^^^^^^
                                                    ^^^^^^^^^^^^^^^^^^^

    إن كان الاستعلام غير مفهوم الهدف، فمن الصعب معرفة الحل الخاص به.

    
    $sql="
    
    SELECT * 
    
    FROM 
    
    BookSpecifications As B
    
    LEFT JOIN 
    
    FeaturesBook AS F 
    
    ON 
    
    F.t1 = B.IDBookSpecifications 
    or 
    F.t2 = B.IDBookSpecifications
    
    
    WHERE F.IDSubject ='145';" ;

     

    مرحبا اخي الكريم 

    بارك لك فيك وزادك من واسع فضله الطريقة تعمل بشكل ممتاز 

     

    والله يا اخوي انا بنفسي الامر لحس مخي قليلا ما أحاول القيام به عباره عن جدولين

    الجدول الأول يحتوي على جميع الوان الكتب وثاني سوف يتم تخزين فيه الألوان التي يختارها المستخدم بحيث يمكنه اختيار اكثر من لون بعدها اقوم بالاستعلام عن الجدول الثاني الذي انا فقط أقوم بحفظ id  فيه التي حصلت عليها من الجدول الاول بمعنى ان الجدول الثاني عباره عن معرفها او ID مختلفات ولكن قد يكون المستخدم قام بعملية تخزين اكثر من معرف لذلك سيكون معرف المستخدم يمتلك اكثر من ID  لنفس الكتاب 

     

    الامر ملخبط شوية ولكن هذا ابسط طريقة وجدتها مناسبه لعمل الامر بسبب رغبتي بفصل هذا الجزء عن جدول البيانات الأساسي حتى يسهل التعامل معها

    • أعجبني 1
  20. مرحبا جميعا

    تحيه طيبه للجميع

    أحاول استعمال LEFT JOIN اكثر من مره لنفس الجدول الامر ناجح لدي ولكن المشكلة في الجملة الشرطيه الكود كالتالي:

    $sql="SELECT * FROM BookSpecifications 
    
    LEFT JOIN FeaturesBook AS A ON A.t1 = BookSpecifications.IDBookSpecifications 
    LEFT JOIN FeaturesBook AS B ON B.t2 = BookSpecifications.IDBookSpecifications 
    WHERE A.IDSubject ='145' " ;

    الكود بشكل أعلاه يعمل بشكل جيد ولكني احتاج الى وضع شرط لسطر الثاني ال IDSubject هنا احصل عليها من جدول FeaturesBook بحيث يصبح كالتالي:

    $sql="SELECT * FROM BookSpecifications 
    
    LEFT JOIN FeaturesBook AS A ON A.t1 = BookSpecifications.IDBookSpecifications 
    LEFT JOIN FeaturesBook AS B ON B.t2 = BookSpecifications.IDBookSpecifications 
    WHERE A.IDSubject ='145' AND  B.IDSubject ='145' " ;

    بمعنى احضر السطرين لو يمتلكون IDSubject المذكور ولكن الان الكود لا يعمل لا اعلم لماذا ولكني احتاج الى وضع شرطين هل يوجد حل مختلف او ان طريقتي خطاء الذي وضعتها ؟ 

    ياليت من لديه فكره عن الامر يفيدنا

    • أعجبني 1
×
×
  • أضف...