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

الفواصل في ListView.separated لا تعمل في Flutter

Flutter Dev

السؤال

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

لدي جدول بيانات اون لاين أحاول عرض اسطر منه في قائمة ListView.separated وارغب ان اضع بين هذا البيانات فواصل separated على سبيل المثال 

يوجد في الجدول الاسم ثم العمر ثم الموقع .. الخ

الان سأقوم بعرض السطر الأول من هذا الجدول ليكون الاسم احمد ثم اضع فاصل ثم العمر ثم فاصل ثم الموقع ثم فاصل .. الخ بشكل هذا

ولكن  ListView.separated لا تعمل في هذا الحالة.  انا اعلم لو كنت اجلب بيانات مجموعة من Row  متعددة من قاعدة البيانات سوف يتم وضع فواصل بين كل Row  ولكن الان  انا أحاول ان اعمل العكس المطلوب عرضه Row واحد ثم اجلب بيانات كل الاعمدة فيه ثم اضع فواصل بين بيانات الاعمدة هذا 

 

هذا الجدول:

+---------+--------------+---------------------+
| user_id | Name         | Age       | Lcation |
+---------+--------------+-----------+---------+
|    1    | Irene        | 22        |   A     |
+---------+--------------+---------------------+

 

وهذا الكود:

 

Container(
      child:

      FutureBuilder(
    future: ApiService().TopOne(ID),
    builder: (context, AsyncSnapshot snapshot) {
      if (snapshot.hasData) {
        return ListView.separated(
          separatorBuilder: (BuildContext context, int index) {
            return Divider(
              thickness: 1,
            );
          },
          scrollDirection: Axis.vertical,
          shrinkWrap: true,
          physics: ScrollPhysics(),
          itemCount: snapshot.data.length,
          itemBuilder: (context, index) {
            return Container(
                child: Column(
              children: [
                Text("${snapshot.data[index]['Name']}"),
                Text("${snapshot.data[index]['Age']}"),
                Text("${snapshot.data[index]['Location']}"),
                Text("${snapshot.data[index]['Others']}"),
              ],
            ));
          },
        );
      } else if (snapshot.hasError) {
        return Center(
            child: Image.asset(
          'assets/nodata.png',
          fit: BoxFit.contain,
          width: 180,
          height: 180,
        ));
      }

 
      return Center(
          child: SizedBox(
        height: MediaQuery.of(context).size.height / 1.3,
        child: Image.asset(
          'assets/no_dataa.png',
          fit: BoxFit.contain,
          width: 180,
          height: 180,
        ),
      ));
    },
  ));
}

 

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

طبعا انا لا ارغب بوضع Divider() بشكل يدوي بعد كل سطر احتاج ان يكون الامر بشكل تلقائي مثل طبيعة عمل ListView.separated 

 

صورة توضح ما أحاول القيام به:

screenshot-2022-08-06_13_35_21_23.thumb.png.83971c3a87ac6106bba2ac9a6ec06c35.png

تم التعديل في بواسطة مروان مروان3
رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

يمكننا محاولة بناء مصفوفة الأبناء children بطريقة ديناميكية، سوف نضع separetor بين العناصر

children: [
                Text("${snapshot.data[index]['Name']}"),
                Text("${snapshot.data[index]['Age']}"),
                Text("${snapshot.data[index]['Location']}"),
                Text("${snapshot.data[index]['Others']}"),
              ],

=>
children: [
  snapshot.data[index].forEach((key, value){
      return Container(
          margin: const EdgeInsets.only( right: 20.0),
                  child:  Text("value"),
      )
  }
],

      
  

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1
بتاريخ 7 دقائق مضت قال مروان مروان3:

بعد تطبيق الكود بشكل أعلاه احصل على الخطاء التالي:



 

عملت تعديل للكود الأول،

الفكرة أن الفاصل العمودي عملته هوامش خارجية للحاوبة container و كل قيمة ضمن Text ويتم المرور على snapshot.data[index] و استخلاص القيم حسب عدد المفاتيح فيها

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1
بتاريخ 13 دقائق مضت قال مروان مروان3:

قمت بتطبيق الكود اخي بشكل أعلاه ثم حصلت على الخطاء التالي:


type 'Null' is not a subtype of type 'Widget'

ما السطر الذي يعيد null؟

بتاريخ منذ ساعة مضت قال مروان مروان3:

صورة توضح ما أحاول القيام به:

لقد فهمت من سؤالك الأول أنك تريد وضع القيم بجانب بعضها مع مسافات أفقية بينها..

ما الفائدة من استخدام ListView.separated إن كان لديك عنصر واحد؟ أليس من الأفضل عمل التصميم بشكل عمود بسيط

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1
بتاريخ 18 دقائق مضت قال مروان مروان3:

هو شغال بشكل هذا ولكن الفواصل لا تظهر بينهم

لقد وجدت فكرة خلال البحث، وهي حقن ال divider لمصفوفة widgets بالاستعانة بمفهوم الإضافة extention من خلال عمل مؤشر يتحرك على القائمة ثم يبني واحدة أخرى ديناميكياً بإضافة widget هي separator

extension IterableExt<T> on Iterable<T> {
  Iterable<T> superJoin(T separator) {
    final iterator = this.iterator;
    if (!iterator.moveNext()) return [];

    final _l = [iterator.current];
    while (iterator.moveNext()) {
      _l..add(separator)..add(iterator.current);
    }
    return _l;
  }
}

وطريقة الاستدعاء تكون:

return Row(
      children: <Widget>[
        const Text('Foo'),
        const Text('Foo'),
        const Text('Bar'),
      ].superJoin(const SizedBox(width: 10,)).toList(),
      
    );

نقوم باستدعاء superJoin وتمرير الفاصل له ليقوم بحقنه بين كل عنصرين.

لطريقة أخرى، عليكا بناء دالة تعيد 

List<Widget>

وتنفيذ الفكرة كالتالي:

  • دالة تعيد قائمة من الواجهات
  • تستقبل قائمة من العناصر 
  • نمرر لها separator
  • نقوم بالمرور على القائمة الأساسية و نأخذ منها العناصر ونضيفهم للقائمة الثانية مع ال separator بالتناوب
  • سوف يمثل استدعاء هذه الدالة قيمة children

List<Widget> createRowChildrenWithPadding(List<Widget> widgets, Padding pading) {
    var joined = List<Widget>();

    for (var i = 0;  i < widgets.length; i++) {
        if ( i != widgets.length - 1)  {
            joined.add(widgets[i]);
            joined.add(padding);
        } else {
            joined.add(widgets[i]);
        }
    }
    return joined;
}

بالنسبة للخطأ السابق،

أعتقد أن حله يكون كالتالي:

return Column(
                  children: <Widget>
                    snapshot.data[index].forEach((key, value){
                      return Container(
                        margin:  EdgeInsets.only(left: 20.0, right: 20.0),
                        child:  Text(snapshot.data[index]['name']),
                      );

                    }
                    ),

                );

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
 ListView.separated(
              separatorBuilder: (BuildContext context, int index) {
                return Divider(
                  thickness: 1,
                );
              },
              shrinkWrap: true,
              itemCount: snapshot.data.length,
              scrollDirection: Axis.vertical,
              physics: ScrollPhysics(),
              itemBuilder: (BuildContext context, int index) {
                return Column(
                  children: <Widget>[
                    snapshot.data[index].forEach((key, value){
                      return Container(
                        margin:  EdgeInsets.only(left: 20.0, right: 20.0),
                        child:  Text(snapshot.data[index]['name']),
                      );

                    }
                    )],

                );
              });

قمت بتطبيق الكود اخي بشكل أعلاه ثم حصلت على الخطاء التالي:

type 'Null' is not a subtype of type 'Widget'

 

تم التعديل في بواسطة مروان مروان3
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ الآن قال Wael Aljamal:

عملت تعديل للكود الأول،

الفكرة أن الفاصل العمودي عملته هوامش خارجية للحاوبة container و كل قيمة ضمن Text ويتم المرور على snapshot.data[index] و استخلاص القيم حسب عدد المفاتيح فيها

مرحبا اخي نعم اعتذر كنت أحاول تطبيق فكرة 

قمت بإرجاع الكود ولكن نفس المشكلة تظهر

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 3 دقائق مضت قال Wael Aljamal:

ما السطر الذي يعيد null؟

لقد فهمت من سؤالك الأول أنك تريد وضع القيم بجانب بعضها مع مسافات أفقية بينها..

ما الفائدة من استخدام ListView.separated إن كان لديك عنصر واحد؟ أليس من الأفضل عمل التصميم بشكل عمود بسيط

هذا السطر الذي يعيد قيمة فارغة :

    snapshot.data[index].forEach((key, value){

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

ما الفائدة من استخدام ListView.separated إن كان لديك عنصر واحد؟ أليس من الأفضل عمل التصميم بشكل عمود بسيط

التصميم عمودي اخي وليس افقي 

يعني الاسم

ثم ياتي اسفله

العمر

ثم ياتي اسفل العمر

الموقع .. الخ

 

ولكني ارغب بوضع بين هذا الاسطر الفاصله

تم التعديل في بواسطة مروان مروان3
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 5 دقائق مضت قال Wael Aljamal:

الصورة التقريبية التي أرفقتها للتصميم

كيف يظهر التصميم حالياً.

نعم اخي

شكل القائمة المعتاد ما أحاول القيام به 

عناصر متاليه 

كل واحد يأتي بعد الذي أعلاه

هو شغال بشكل هذا ولكن الفواصل لا تظهر بينهم

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 5 ساعات قال Wael Aljamal:

لقد وجدت فكرة خلال البحث، وهي حقن ال divider لمصفوفة widgets بالاستعانة بمفهوم الإضافة extention من خلال عمل مؤشر يتحرك على القائمة ثم يبني واحدة أخرى ديناميكياً بإضافة widget هي separator


extension IterableExt<T> on Iterable<T> {
  Iterable<T> superJoin(T separator) {
    final iterator = this.iterator;
    if (!iterator.moveNext()) return [];

    final _l = [iterator.current];
    while (iterator.moveNext()) {
      _l..add(separator)..add(iterator.current);
    }
    return _l;
  }
}

وطريقة الاستدعاء تكون:


return Row(
      children: <Widget>[
        const Text('Foo'),
        const Text('Foo'),
        const Text('Bar'),
      ].superJoin(const SizedBox(width: 10,)).toList(),
      
    );

نقوم باستدعاء superJoin وتمرير الفاصل له ليقوم بحقنه بين كل عنصرين.

لطريقة أخرى، عليكا بناء دالة تعيد 


List<Widget>

وتنفيذ الفكرة كالتالي:

  • دالة تعيد قائمة من الواجهات
  • تستقبل قائمة من العناصر 
  • نمرر لها separator
  • نقوم بالمرور على القائمة الأساسية و نأخذ منها العناصر ونضيفهم للقائمة الثانية مع ال separator بالتناوب
  • سوف يمثل استدعاء هذه الدالة قيمة children


List<Widget> createRowChildrenWithPadding(List<Widget> widgets, Padding pading) {
    var joined = List<Widget>();

    for (var i = 0;  i < widgets.length; i++) {
        if ( i != widgets.length - 1)  {
            joined.add(widgets[i]);
            joined.add(padding);
        } else {
            joined.add(widgets[i]);
        }
    }
    return joined;
}

بالنسبة للخطأ السابق،

أعتقد أن حله يكون كالتالي:


return Column(
                  children: <Widget>
                    snapshot.data[index].forEach((key, value){
                      return Container(
                        margin:  EdgeInsets.only(left: 20.0, right: 20.0),
                        child:  Text(snapshot.data[index]['name']),
                      );

                    }
                    ),

                );

 

اهلا اخي الكريم اعتذر على تأخر الرد

بالنسبة الي الطريقة الأولى حقيقه تبدو معقده قليلا علي 

اما التعديل الثاني ما تزال نفس المشكلة 

type 'Null' is not a subtype of type 'Widget'

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 4 دقائق مضت قال مروان مروان3:

بالنسبة الي الطريقة الأولى حقيقه تبدو معقده قليلا علي 

هذه أفضل طريقة حاول مجدداً تطبيقها. أرجو تجاهل الحل السابق الأول

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...