إتقان أدوات واجهة مستخدم Flutter: الوظائف النقية Pure funcation / widgets

 

إتقان أدوات واجهة مستخدم Flutter:  الوظائف النقية Pure funcation / widgets
شرح إتقان أدوات واجهة مستخدم Flutter:  الوظائف النقية Pure funcation / widgets

شرح إتقان أدوات واجهة مستخدم Flutter:  الوظائف النقية Pure funcation / widgets


إنشاء واجهات مستخدم فعالة ويمكن التنبؤ بها: أدوات واجهة مستخدم وظيفية خالصة لتطوير Flutter

يركز هذا الموضوع على الفوائد الرئيسية لأدوات واجهة المستخدم الوظيفية البحتة:

الكفاءة: تعتبر الوظائف البحتة فعالة بطبيعتها نظرًا لطبيعتها عديمة الحالة، والتي يمكن أن تعمل على تحسين الأداء.

يمكن التنبؤ به: تنتج الدوال الخالصة دائمًا نفس المخرجات لنفس المدخلات، مما يؤدي إلى تبسيط الاختبار وتصحيح أخطاء تطبيقات Flutter.


تطوير Flutter: التركيز الرئيسي لهذا الموضوع.

Flutter Framework: أداة واجهة المستخدم الوظيفية الخالصة لإطار Flutter لإنشاء تطبيقات الهاتف المحمول.

لغة برمجة Dart: Dart هي اللغة الأساسية المستخدمة في تطوير Flutter.

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

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

تصميم واجهة المستخدم: يتناول هذا الموضوع تطوير أنواع محددة من عناصر واجهة المستخدم في Flutter.

إدارة الحالة: على الرغم من أن عناصر واجهة مستخدم الوظائف الخالصة عديمة الحالة، فإن فهم إدارة الحالة في Flutter يعد أمرًا تكميليًا.

تحسين الأداء: كما ذكرنا من قبل، تساعد الوظائف النقية على تحسين الأداء.

الاختبار وتصحيح الأخطاء: إن إمكانية التنبؤ بأدوات واجهة المستخدم الوظيفية البحتة يمكن أن تجعل اختبار وتصحيح كود Flutter الخاص بك أسهل.


شرح كيفية عمل Pure widgets

بكل بساطه هي عباره عن widget او funcation مستقله بذاتها وغير معتمده على اي تفاعل اخر وفي هذا المثال لدينا RadioButton يتم عمل list تحتوي على مجموعه من العناصر يتم ارسالها للwidget وهناك يتم عمل العمليه الخاصه واظهار النتيجه وبهذا تكون ال widget مستقله بذاتها وغير معتمده على اي widget اخرى وايضا عندما يحدث لها error / reBuild تحديث لهذه widget فقط وليس screen بشكل كامل .

وبهذا نحافظ على الاداء بشكل كبير .

main.dart


//--- cubit  ---//
  // int userType = 1;
  //
  // List<String> dataRadio = [
  //   'ahmed',
  //   'mohamed',
  //   'mazen'
  // ];

Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            StringsRadiosSelector(
              list: context.read<MainBloc>().dataRadio.asMap().inverse,
              initialValue: 0,
              title: 'Select data',
              onChanged: (value) {
                if (value != null) {
                  context.read<MainBloc>().userType = value;
                }
              },
            ),
            ElevatedButton(onPressed: (){
              var data = context.read<MainBloc>().dataRadio.asMap().inverse;
              print(data.values.toList());

            }, child: const Text('Test Button'))
          ],
        ),
      )
    );
    

widgets.dart

extension InvertMap<K, V> on Map<K, V> {
  Map<V, K> get inverse =>
      Map.fromEntries(entries.map((e) => MapEntry(e.value, e.key)));
}

class StringsRadiosSelector extends StatefulWidget {
  const StringsRadiosSelector({
    super.key,
    required this.list,
    required this.initialValue,
    required this.onChanged,
    required this.title,

  });

  final Map<dynamic, dynamic> list;
  final int initialValue;
  final ValueChanged<int?> onChanged;
  final String title;

  @override
  State<StringsRadiosSelector> createState() => _StringsRadiosSelectorState();
}

class _StringsRadiosSelectorState extends State<StringsRadiosSelector> {
  int selectedValue = 0;
  List<dynamic> values = [];
  List<dynamic> keys = [];

  @override
  void initState() {
    selectedValue = widget.initialValue;
    values = widget.list.keys.toList();
    keys = widget.list.values.toList();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          widget.title,
        ),
        const SizedBox(
          height: 8.0,
        ),
        SizedBox(
          height: 30.00,
          child: ListView.builder(
            physics: const BouncingScrollPhysics(),
            scrollDirection: Axis.horizontal,
            itemCount: values.length,
            itemBuilder: (context, index) => Row(
              children: [
                RadioTheme(
                  data: RadioThemeData(
                    fillColor: MaterialStateProperty.all(Colors.green),
                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                    visualDensity: VisualDensity.compact,
                  ),
                  child: Radio<int>(
                    value: keys[index],
                    groupValue: selectedValue,
                    onChanged: (value) {
                      setState(() {
                        selectedValue = value!;
                        widget.onChanged(value);
                      });
                    },
                    activeColor: Colors.green,
                  ),
                ),
                const SizedBox(
                  height: 8.0,
                ),
                Text(
                  values[index],
                ),
                const SizedBox(
                  height: 16.0,
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

تعليقات