بحث باسم الموضوع المطلوب

إلى مصممي واجهة المستخدم وتجربة المستخدم، إليكم دليلاً سريعًا للشبكة المحمولة لشاشات iOS وAndroid.

 

او رابط الصوره من هنا :  https://sajaf-fon.blogspot.com/2024/11/ios-android-ui-ux.html/

لمعرفه شيء جديد وحصري في برمجه فلاتر

لم يتم العثور على الملف 'Flutter/Flutter.h'

https://onlyflutter.com/flutter-flutter-h-file-not-found/

عند تطوير تطبيق Flutter الخاص بك لنظام iOS، قد تواجه خطأً يشير إلى عدم العثور على ملف "Flutter/Flutter.h" . في هذا المنشور، سنستعرض الحل لمساعدتك في حل هذا الخطأ وتشغيل تطبيقك بسلاسة على نظام iOS.


لماذا تعلم SwiftUI كمطور Flutter؟

https://verygood.ventures/blog/why-learn-swiftui-as-a-flutter-developer/

هناك العديد من الحالات الهامشية التي لا يغطيها Flutter. على مدار 10 سنوات، واصلت Apple دفع iOS وiPadOS وmacOS إلى الأمام من خلال إزالة الوظائف من التطبيق الأساسي وإضافتها في مكان آخر حتى تتمكن من التفاعل معها دون تشغيل التطبيق على الإطلاق. لذلك، في هذه المقالة، ناقش فريق VGV مقارنة SwiftUI وFlutter وناقش سبب رغبتك في تعلم SwiftUI كمطور Flutter وكيف يمكن أن تبدو التجربة.


تأمين البيانات باستخدام تشفير AES وفك التشفير في Flutter

https://medium.com/@eebrahimjoy/secure-data-with-aes-encryption-decryption-in-flutter-e401a14cdab7/

في هذه المقالة، سنتناول نهجًا خطوة بخطوة لتنفيذ تشفير وفك تشفير AES (معيار التشفير المتقدم) في تطبيق Flutter باستخدام Dart.


كيفية استخدام الرسوم المتحركة Flare في Flutter لإنشاء واجهات مستخدم جذابة وجميلة

https://medium.com/stackademic/how-to-use-flare-animations-in-flutter-to-create-engaging-and-beautiful-uis-c064891b5645/

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

لعمل شخصية المستخدم (Persona) و خريطة تجربة المستخدم (User Journey Map) لخدمة توصيل الطعام، يمكنك اتباع الخطوات التالية:

1. إنشاء شخصية المستخدم (Persona):

   - الاسم: اختر اسماً مناسباً للشخصية، مثلاً "علي" أو "سارة".

   - العمر: حدد الفئة العمرية، مثلًا: 25 سنة.

   - الوظيفة: اختر وظيفة توضح مستوى الدخل وأنماط الحياة، مثل موظف بدوام كامل، أو طالب.

   - الهوايات والاهتمامات: أضف بعض الاهتمامات التي تدعم استخدامه لتطبيق توصيل الطعام.

   - الأهداف: ما الذي يأمل المستخدم في تحقيقه باستخدام التطبيق؟ مثال: توصيل سريع، توفير طعام صحي.

   - التحديات: أي صعوبات يمكن أن تواجهه؟ مثل تكلفة التوصيل العالية، أو خيارات محدودة للطعام الصحي.


2. عمل خريطة تجربة المستخدم (User Journey Map):

   - المرحلة الأولى - الوعي: كيف يتعرف المستخدم على خدمة التوصيل؟ مثلًا عبر الإعلانات أو توصيات الأصدقاء.

   - المرحلة الثانية - البحث عن خيارات: كيف يبحث عن الطعام؟ مثلاً استخدام فلتر للمطاعم حسب المسافة أو نوع الطعام.

   -  المرحلة الثالثة - الطلب: هنا سيبدأ المستخدم بإضافة الطعام إلى السلة والتأكيد.

   - المرحلة الرابعة - التوصيل: تعقب الطلب وتحديد وقت الوصول المتوقع.

   - المرحلة الخامسة - التقييم: قد يقوم بتقييم الخدمة بعد وصول الطعام.

مجاناً 8 دورات تدريبية حول أمن الحوسبة السحابية .

تعرف على كيفية بدء مهنة في مجال الحوسبة السحابية .

تتضمن هذه الدورات التدريبية السحابية على وجه الخصوص بعض مسارات التعلم الرائعة لأولئك الذين يبدأون من الصفر .


💥 المقدمة

1. الوظائف في مجال الحوسبة السحابية

Careers in Cloud Computing


2. الأمن السيبراني بإستخدام الحوسبة السحابية

Cyber Security with Cloud Computing


💥 Microsoft Azure

3. البدء في أستخدام Microsoft Azure

Getting Started with Microsoft Azure


4. التدريب الأساسي على إدارة Azure

Azure Administration Essential Training


5. إعداد شهادة أساسيات Azure (AZ-900)

Azure Fundamentals (AZ-900) Cert Prep


💥 AWS آمازون السحابية

6. AWS لغير المهندسين

AWS for Non-Engineers


7. ممارس السحابة في AWS

AWS Cloud Practitioner


8. الترحيل إلى AWS

Migrating to AWS


https://linktr.ee/mikemillercyber

لتتعلم شي جديد في برمجه فلاتر

أتمتة نشر تطبيق Flutter iOS باستخدام GitHub Actions وCodemagic CLI

https://canopas.com/automate-flutter-ios-app-deployment-with-github-actions-and-codemagic-cli-4d063ea6ef08

في هذه المقالة، ستتعلم كيفية استخدام أدوات Codemagic CLI مع GitHub Actions لنشر تطبيق Flutter على iOS.


الحفاظ على مزامنة الأدوات مع بياناتك

https://blog.burkharts.net/keeping-widgets-in-sync-with-your-data/

هذه المقالة هي الجزء الثاني من استخدام كائنات الوكيل. في هذه المقالة، ستتعلم كيفية تحسين معالجة الأخطاء، وكيفية عرض كائن وكيل في أماكن متعددة في وقت واحد، وكيفية استخدام الأوامر لكتابة كود أنيق.


دعونا نتحدث عن تسربات الذاكرة في Dart و Flutter

https://dcm.dev/blog/2024/10/21/lets-talk-about-memory-leaks-in-dart-and-flutter/

في هذه المقالة، سوف نستكشف تسريبات الذاكرة في Dart و Flutter، وكيف تحدث، وأهميتها في ممارسات الترميز، والحلول لتصحيح تسريبات الذاكرة وتحديدها مثل DevTools و Leak Tracker والتحول إلى اليسار بالاعتماد على أدوات التحليل الثابتة مثل DCM وكيف يمكنها منع مثل هذه التسريبات من التسلل إلى قاعدة التعليمات البرمجية الخاصة بك.


كيفية إدارة رؤوس HTTP ومعلمات الاستعلام في Flutter

https://medium.com/@blup-tool/how-to-manage-http-headers-and-query-parameters-in-flutter-2a2381b3285f/

تعرف على كيفية إضافة رؤوس مخصصة ومعلمات استعلام إلى طلبات HTTP في Flutter. أتقن تفاصيل تكامل واجهة برمجة التطبيقات والاتصال.

أدوات للكشف عن بياناتك الشخصية على الويب المظلم DarkWeb

فيما يلي تجميع لأفضل 4 أدوات مجانية قم بإستخدامها بإنتظام (كل 4 أشهر) للتحقق مما يعرفه المتسللون عنك بالفعل .


1. Pentester


🔗 رابط : https://pentester.com/

اكتشف بصمتك الرقمية بنقرتين بسيطتين .

أداة رائعة حقًا لمعرفة ما إذا كانت بياناتك قد تعرضت للتسريب حتى تتمكن من تغيير كلمات المرور الخاصة بك بسرعة وعدم ترك أي فرصة للمتسللين .


2. HackCheck


🔗 الرابط : https://hackcheck.io


باختصار HackCheck هو محرك بحث عن تسريبات البيانات .

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


3. Have I been PWNED?


🔗 الرابط : http://haveibeenpwned.com/


واحدة من أقدم الأدوات للتحقق مما إذا كانت بياناتك الشخصية قد تعرضت للاختراق والتسريب إلى الويب المظلم .


يحتوي هذا الموقع أيضًا على قسم ضخم يحتوي على أكبر وأحدث خروقات البيانات.


وُلدت Have I Been Pwned في أعقاب إحدى أكبر عمليات الاختراق لحسابات العملاء في التاريخ - اختراق Adobe .

في عام 2013، تم اختراق حوالي 153 مليون حساب Adobe، ويحتوي كل منها على:

•معرف داخلي

•اسم المستخدم

•بريد إلكتروني

•كلمة المرور المشفرة وما إلى ذلك .


4. NameScan.io

🔗 الرابط : http://namescan.io


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


قم بتحليل مدى أمان ملفك الشخصي على مواقع الويب التي شاركت بريدك الإلكتروني فيها .


💡دورات وشهادات مجانية اختبار الاختراق والقرصنة الأخلاقية مع اعتماد CPD

- مهندس اختبار الاختراق

Penetration Testing Engineer


https://alison.com/course/penetration-testing-engineer/


- تقييم نقاط الضعف واختبار الاختراق (VAPT)

Vulnerability Assessment and Penetration Testing (VAPT)


https://alison.com/course/vulnerability-assessment-and-penetration-testing-vapt/


- ChatGPT (Open AI) الأمن والخصوصية والقرصنة الأخلاقية

ChatGPT (Open AI) Security, Privacy & Ethical Hacking


https://alison.com/course/chatgpt-open-ai-security-privacy-and-ethical-hacking/


- القرصنة الأخلاقية

Professional Ethical Hacking


https://alison.com/course/professional-ethical-hacking/


- مستشار اختبار الاختراق

Penetration Testing Consultant


https://alison.com/course/penetration-testing-consultant/

كيفية إضافة الظلال إلى عناصر واجهة المستخدم في Flutter

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

جدول المحتويات

إضافة الظلال إلى الحاوية

  • استخدم فئة BoxDecoration لإضافة الظلال إلى عناصر واجهة المستخدم في Flutter
  • استكشاف فئة BoxShadow

1. BlurRadius

2. أسلوب التمويه

3. اللون

4. الإزاحة

5. انتشار نصف القطر

  • استخدام عناصر واجهة المستخدم المتعددة BoxShadow لإضافة الظلال في Flutter
  • إضافة الظلال إلى الأدوات الأخرى
  • تغليف عناصر واجهة المستخدم باستخدام حاوية لإضافة الظلال في Flutter
  • خاتمة

إضافة الظلال إلى الحاوية
سنبدأ بإضافة ظل إلى إحدى الأدوات الأكثر استخدامًا في Flutter: Containerالأداة. أولاً، قمنا بإعداد تطبيق بسيط داخل ملفنا main.dartيعرض Containerأداة مركزية بلون خلفية أزرق.

CMD...

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Container(
            width: 200,
            height: 200,
            color: Colors.blue,
            child: const SizedBox.shrink(),
          ),
        ),
      ),
    );
  }
}
CMD.....

عندما نقوم بتشغيل main.dartالملف، سوف ترى لونًا أزرقًا Containerمعروضًا في وسط الشاشة.

الآن دعونا ننتقل إلى القسم التالي حيث سنقوم بتطبيق الظلال على Containerالأداة.

استخدم فئة BoxDecoration لإضافة الظلال إلى عناصر واجهة المستخدم في Flutter
Containerيمكن إضافة الظلال إلى عنصر واجهة مستخدم في Flutter باستخدام BoxDecorationالفئة. تتيح لك هذه الفئة تخصيص Containerمظهر عنصر واجهة المستخدم، بما في ذلك الظلال.



CMD...

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Container(
            width: 200,
            height: 200,
            decoration: const BoxDecoration(
              color: Colors.white,
              boxShadow: [
                BoxShadow(
                  blurRadius: 25,
                  blurStyle: BlurStyle.normal,
                  color: Colors.black,
                  offset: Offset.zero,
                  spreadRadius: 2,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

CMD.....

في الكود أعلاه، استبدلنا colorخاصية the Containerبالخاصية decoration. داخل decorationالخاصية، نستخدم BoxDecorationمثيلًا. BoxDecorationيسمح لنا المثيل بتعيين لون الخلفية وإضافة تأثير ظل إلى Container.

داخل BoxDecorationالمثيل، قمنا بتعيين colorsالخاصية إلى Colors.white، والخاصية boxShadowإلى قائمة تحتوي على BoxShadowمثيل واحد لإضافة ظل. BoxShadowيأخذ المثيل الخصائص التالية:

  • blurRadius:يحدد عدم وضوح الظل. تؤدي القيمة الأعلى إلى إنشاء ظل أكثر نعومة.
  • blurStyle:يحدد نمط التمويه المطبق على الظل. في هذه الحالة، يتم ضبطه على تمويه عادي.
  • color:تعيين لون الظل إلى اللون المحدد، والذي في هذا المثال تم تعيينه إلى اللون الأسود.
  • offset:يحدد موضع الظل. هنا، Offset.zeroيعني أن الظل يقع مباشرة أسفله Containerدون أي إزاحة في أي اتجاه.
  • spreadRadius:يتحكم في مدى انتشار الظل من حواف Container.
عندما نقوم بتشغيل التطبيق، سوف ترى لونًا أبيض Containerمع ظل داكن حوله.
في القسم القادم من هذه التدوينة، سنلقي نظرة عن كثب على كل خاصية من خصائص BoxShadowالفئة.

استكشاف فئة BoxShadow
لقد تعلمنا حتى الآن أن هذه BoxShadowالفئة تسمح لنا بإنشاء تأثيرات ظلية Containerللأدوات. BoxShadowوتوفر هذه الفئة الكثير من التخصيصات. دعنا نستعرض خيارات التخصيص لنرى ما يمكننا تحقيقه باستخدامها.

1. BlurRadius
تتحكم الخاصية blurRadiusفي مدى ضبابية الظل. تؤدي القيمة الأكبر، مثل 100، إلى إنشاء ظل أكثر نعومة ووضوحًا. وعلى العكس من ذلك، يؤدي تعيين blurRadiusإلى إلى إلى 0إنشاء ظل ذو حواف حادة.

CMD...

BoxShadow(
  blurRadius: 100,
  blurStyle: BlurStyle.normal,
  color: Colors.black,
  offset: Offset.zero,
  spreadRadius: 2,
),

CMD.....
في هذا المثال، قمنا بتعيين الخيار blurRadiusإلى 100لجعل الظل ناعمًا للغاية وأكثر انتشارًا.

2. أسلوب التمويه
تعرف الخاصية blurStyleالموجودة في BoxShadowالفصل على نمط التمويه المطبق على الظل.
CMD...

BoxShadow(
  blurRadius: 100,
  blurStyle: BlurStyle.solid,
  color: Colors.black,
  offset: Offset.zero,
  spreadRadius: 2,
),

CMD.....
في الكود أعلاه، نستخدم BlurStyle.solid، والذي ينشئ ظلًا صلبًا وحاد الحواف.
3. اللون
تسمح لنا الخاصية colorالموجودة في BoxShadowالفصل بتحديد لون الظل.

CMD...

BoxShadow(
  blurRadius: 100,
  blurStyle: BlurStyle.solid,
  color: Colors.blue,
  offset: Offset.zero,
  spreadRadius: 2,
),

CMD.....

في هذا الكود، قمنا بتغيير colorإلى Colors.blue، مما سيؤدي إلى تحويل الظل إلى اللون الأزرق. يمكنك استخدام أي لون تريده، أو حتى التدرجات اللونية للحصول على تأثيرات أكثر إبداعًا.

4. الإزاحة
تحدد الخاصية offsetالموجودة في BoxShadowالفصل موضع الظل بالنسبة للأداة.
CMD...

BoxShadow(
  blurRadius: 100,
  blurStyle: BlurStyle.solid,
  color: Colors.blue,
  offset: Offset(25, 25),
  spreadRadius: 2,
),

CMD.....
في هذه الحالة، قمنا بتعيين القيمة offsetإلى Offset(25, 25)، وهذا من شأنه تحريك وحدات بكسل الظل 25إلى اليمين ووحدات 25بكسل أسفل الأداة. وهذا من شأنه أن يخلق تأثير ظل يعطي انطباعًا بأن الضوء قادم من الاتجاه العلوي الأيسر.
يمكننا أيضًا استخدام القيم السلبية لتحريك الظل في الاتجاه المعاكس.
CMD...

BoxShadow(
  blurRadius: 100,
  blurStyle: BlurStyle.solid,
  color: Colors.blue,
  offset: Offset(-25, -25),
  spreadRadius: 2,
),

CMD.....
في الوقت الحالي، قمنا بتغيير offsetإلى Offset(-25, -25)، وهذا من شأنه أن يحرك وحدات بكسل الظل 25إلى اليسار 25والبكسلات الموجودة أعلى الأداة. ويعطي هذا التغيير انطباعًا بأن الضوء قادم من الاتجاه السفلي الأيمن.

5. انتشار نصف القطر
تحدد الخاصية spreadRadiusالموجودة في BoxShadowالفصل مدى انتشار الظل من حدود الأداة.


CMD...

BoxShadow(
  blurRadius: 100,
  blurStyle: BlurStyle.solid,
  color: Colors.blue,
  offset: Offset.zero,
  spreadRadius: 50,
),

CMD.....

في هذا المثال، قمنا بتعيين spreadRadiusإلى 50، مما يعني أن الظل سيمتد 50بكسلًا من حواف الأداة.

استخدام عناصر واجهة المستخدم المتعددة BoxShadow لإضافة الظلال في Flutter
ربما لاحظت أن boxShadowخاصية الفصل BoxDecorationتأخذ قائمة من BoxShadowالحالات. وهذا يعني أنه يمكنك تطبيق ظلال متعددة.

CMD...

Container(
  width: 200,
  height: 200,
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(8),
    boxShadow: [
      BoxShadow(
        blurRadius: 5,
        color: Colors.blue.withOpacity(0.8),
        offset: const Offset(5, 5),
        spreadRadius: 5,
      ),
      BoxShadow(
        blurRadius: 5,
        color: Colors.green.withOpacity(0.8),
        offset: const Offset(-5, -5),
        spreadRadius: 5,
      ),
    ],
  ),
),

CMD.....

في مقتطف التعليمات البرمجية هذا، أضفنا مثيلين BoxShadowداخل boxShadowالخاصية. كل مثيل له لون مختلف، وواحد له إزاحة موجبة بينما الآخر له إزاحة سالبة. يؤدي هذا إلى إنشاء ظل حول Containerالأداة بألوان متعددة.
إضافة الظلال إلى الأدوات الأخرى
حتى الآن، نقوم بإنشاء ظلال باستخدام Containerالأداة مع BoxDecorationالفصل. تحتوي بعض الأدوات أيضًا على ظلال افتراضيًا ويمكن تعديلها بسهولة باستخدام الخصائص. خذ Cardالأداة كمثال.
CMD...

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Center(
          child: Card(
            color: Colors.blue,
            elevation: 20,
            shadowColor: Colors.black,
            child: SizedBox(
              width: 200,
              height: 200,
            ),
          ),
        ),
      ),
    );
  }
}

CMD.....
في هذا الكود، نستخدم Cardعنصر واجهة المستخدم ذي الخلفية الزرقاء. ونضبط elevationto 20لجعل الظل أكثر بروزًا، و shadowColorto Colors.blackلجعل الظل داكنًا.
كما ترى، فإن تغيير الظل على Cardالأداة بسيط! ومع ذلك، BoxShadowفإن الطريقة أكثر مرونة. لحسن الحظ، في معظم الحالات، يمكنك تغليف أدواتك باستخدام Containerأداة، وسنتناول المزيد حول هذا في القسم التالي.

تغليف عناصر واجهة المستخدم باستخدام حاوية لإضافة الظلال في Flutter
في الحالات التي لا تكون فيها الظلال المحددة مسبقًا كافية، يمكنك تغليف الأداة باستخدام Containerأداة وتطبيق ظل مخصص BoxDecoration، كما تمت مناقشته سابقًا.

CMD...

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Container(
            decoration: BoxDecoration(
              boxShadow: [
                BoxShadow(
                  blurRadius: 25,
                  blurStyle: BlurStyle.normal,
                  color: Colors.grey.withOpacity(0.5),
                  offset: Offset.zero,
                  spreadRadius: 25,
                ),
              ],
            ),
            child: const Card(
              color: Colors.blue,
              child: SizedBox(
                width: 200,
                height: 200,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

CMD.....
في مقتطف التعليمات البرمجية هذا، قمنا بتغليف Cardالأداة باستخدام Containerأداة. ومن خلال القيام بذلك، يمكننا تطبيق تأثير ظل مخصص على البطاقة باستخدام BoxShadowالفئة. هنا، قمنا بإنشاء ظل مع a blurRadiusof 25وa blurStyleof BlurStyle.normalوa colorof grey مع تعتيم 0.5وan offsetof Offset.zeroوa spreadRadiusof 25.

لقد قمنا أيضًا بإزالة الخاصيتين elevationand shadowColorمن Cardالأداة للتأكد من أن الظل المخصص وظل البطاقة الافتراضي لا يتداخلان مع بعضهما البعض.

خاتمة
عندما يتعلق الأمر بـ Flutter، فهناك العديد من الطرق لإضافة الظلال إلى عناصر واجهة المستخدم الخاصة بك. يمكنك دائمًا استخدام Containerعنصر واجهة المستخدم مع BoxDecorationالفئة. تحتوي بعض عناصر واجهة المستخدم أيضًا على ظلال محددة مسبقًا يمكن تغييرها باستخدام الخصائص.

قم بإنشاء أيقونات الوسائط الاجتماعية هذه باستخدام HTML وCSS فقط 🔥

الكود https://github.com/atherosai/ui/tree/main/socials-05/ 🧑‍💻



الصين تخطو خطوة مبهرة نحو مستقبل الفضاء🚀 دمج الذكاء الاصطناعي مع تكنولوجيا الأقمار الصناعية يمثل نقلة نوعية في مسيرة الصين 🇨🇳 مع تكنولوجيا الفضاء

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


ويمثل هذا الإطلاق خطوة حاسمة في استراتيجية الصين الأوسع لدمج الذكاء الاصطناعي  مع تكنولوجيا الفضاء ويضع هونغ كونغ كلاعب رئيسي في هذه التطورات.

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


وشركة ADA Space، التي تقف وراء تصنيع هذا الابتكار، هي مؤسسة رئيسية تدعمها حكومة هونغ كونغ وقد شاركت في العديد من المشاريع ذات الأولوية الوطنية، بما في ذلك برنامج استكشاف القمر في الصين.


وتقول الجامعة:

https://focus.cuhk.edu.hk/en/20241009/debut-satellite-begins-new-chapter-of-hong-kong-aerospace/050-science-engineering-technology-en/


انه إنجاز جامعة هونغ كونغ للعلوم والتكنولوجيا في الوقت المناسب للاحتفال بالذكرى 75 لتأسيس جمهورية الصين الشعبية.


وان القمر الصناعي  "Hong Kong Youth Scientific Innovation"، طورته جامعة هونغ كونغ للعلوم والتكنولوجيا بالتعاون مع ADA Space، و تم إطلاقه  إلى الفضاء في ميناء هايانج أورينتال الفضائي في مقاطعة شاندونغ باستخدام مركبة الإطلاق Smart Dragon 3.


و سيجمع البيانات البيئية والجغرافية في هونغ كونغ ومنطقة خليج قوانغدونغ-هونغ كونغ-ماكاو الكبرى لإعلام الاستجابات للكوارث الطبيعية العالمية وبناء المدن الذكية. 


ويمثل الإطلاق ميلاد أول قمر صناعي تم تطويره بواسطة مؤسسة تعليمية عليا في هونغ كونغ، ومعلمًا مهمًا في أبحاث الفضاء في جامعة هونغ كونغ للعلوم والتكنولوجيا. 


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


وفي مؤتمر صحفي، قالت الأستاذة كوان مي بو، أستاذة الجغرافيا وإدارة الموارد (GRM) ومديرة معهد ISEIS:

 إن هذا الاختراق من شأنه أن يمكّن من جمع البيانات بشكل أكثر مباشرة ومنهجية للتنبؤ بالكوارث والاستجابة لها. وأضافت أن النتائج ستنطبق أيضًا على تصميم وتطوير المدن الذكية. 


وقال الأستاذ كوان، الذي يشغل منصب كبير العلماء في مجموعة أقمار CUHK الصناعية: 

"تتمتع CUHK بخبرة لسنوات عديدة في مجال أبحاث الأقمار الصناعية وتحليل البيانات. بالإضافة إلى الحصول على الدعم القوي من البر الرئيسي، فإننا مرتبطون ارتباطًا وثيقًا بالعالم من خلال مساعدة البلدان في منطقة آسيا والمحيط الهادئ في الوقاية من الكوارث". 


وقال الأستاذ ما بيفينج، كبير مهندسي مشروع القمر الصناعي في CUHK ونائب رئيس قسم GRM:

 "إن قمر جامعة هونغ كونغ الصناعي سيمكن فريقنا من تطوير أساليب جديدة تعتمد على البيانات مع زيادة دقة التنبؤ بنسبة تصل إلى 85٪". 

‏تحقق مما إذا كان حسابك أو حساب مؤسستك قد تعرض للتسريب على الويب المظلم Dark Web

يمكنك التسجيل مجانًا على منصة StealthMole للتحقق من ذلك . 


https://stealthmole.com/

flutter تعلم كل جديد

 كيفية إعداد Flutter وFirebase بنكهات متعددة باستخدام FlutterFire CLI

https://codewithandrea.com/articles/flutter-firebase-multiple-flavors-flutterfire-cli/

إذا كان تطبيق Flutter الخاص بك يدعم نكهات متعددة ويتصل بـ Firebase، فستحتاج إلى بعض الإعدادات الإضافية لضمان توافق كل نكهة مع بيئة Firebase مختلفة . في هذه المقالة، ستتعلم كيفية دمج Firebase في تطبيق Flutter متعدد النكهات الخاص بك.


إظهار جدران الدفع في Flutter باستخدام RevenueCat

https://onlyflutter.com/show-paywalls-in-flutter-using-revenuecat/

تخبر جدران الدفع المستخدمين بضرورة إجراء عملية شراء داخل التطبيق للمتابعة. تقدم RevenueCat جدران دفع مُجهزة مسبقًا، مما يجعل عملية الإعداد أسرع وأسهل. في هذا المنشور، سنشرح كيفية عرض جدران الدفع في Flutter باستخدام RevenueCat.


تعزيز فريق التطوير الخاص بك باستخدام Dart Frog وAWS

https://verygood.ventures/blog/supercharging-your-development-team-with-dart-frog-and-aws/

في Fluttercon USA 2024، أظهر فريق VGV كيف يمكن لـ Dart Frog التكامل بسلاسة مع موارد AWS لبناء حل سحابي متكامل يحافظ على الفصل الواضح للمخاوف بين الواجهة الأمامية والخلفية مع تسريع التطوير لفرق الهندسة.


تحسين إدارة أعلام الميزات في Flutter باستخدام Firebase: نهج مبسط II: توسيع أنواع أعلام الميزات

https://medium.com/@vortj/improving-feature-flag-management-in-flutter-with-firebase-a-streamlined-approach-ii-expanding-08baa8d706a7/

هذا دليل خطوة بخطوة حول كيفية جعل علامات الميزات أكثر مرونة من خلال دعم أنواع بيانات متعددة مثل boolو intوString

‏🔗📚🏫 يحتوي هذا الرابط على برامج وموارد تعليمية + كتب + دورات والمزيد :

‏- علم البيانات Data Science


‏- بايثون Python 


‏- الذكاء الاصطناعي AI


‏- البيانات الضخمة Big Data 


‏- تحليلات البيانات Data Analytics


‏- منصة جوجل السحابية Google I Cloud


‏- تكنولوجيا المعلومات Information Technology 


‏- ماجستير في إدارة الأعمال Master of Business Administration


‏- الأمن السيبراني Cybersecurity 

https://drive.google.com/drive/mobile/folders/1CgN7DE3pNRNh_4BA_zrrMLqWz6KquwuD?pli=1/

مقالات رهيبه برمجه فلاتر Flutter

 6 خطوات أساسية يجب اتباعها قبل إطلاق تطبيق Flutter التالي

https://codewithandrea.com/articles/key-steps-before-launching-flutter-app/

إن إطلاق تطبيق Flutter لا يقتصر على كتابة التعليمات البرمجية والنقر على زر "النشر". لزيادة فرص نجاحك، هناك خطوات أساسية قبل الإصدار يجب عليك اتخاذها. في هذه المقالة، سنستعرض ستة تحديات رئيسية يجب عليك مراعاتها قبل إطلاق تطبيقك.


ما هي التدفقات في Flutter

https://onlyflutter.com/what-are-streams-in-flutter/

يقدم Flutter عدة طرق للتعامل مع البيانات غير المتزامنة، حيث تعد Futures هي الطريقة الأكثر استخدامًا. في حين أن Futures مثالية للانتظار على نتيجة واحدة، فإن التدفقات مثالية للمواقف التي تصل فيها البيانات في أجزاء. في هذا المنشور، سنستكشف كيفية استخدام التدفقات بشكل فعال في Flutter لبناء تطبيقات سريعة الاستجابة وديناميكية.


Fluttercon USA 2024: أهم الأفكار والدروس المستفادة

https://verygood.ventures/blog/fluttercon-usa-2024-key-insights-and-learnings/

في هذه المقالة، تعرف على أهم النقاط المستفادة من VGV، والرؤى المستفادة من جلساتنا، وأحدث الاتجاهات في تطوير Flutter.


كيفية إنشاء تطبيق Flutter متجاوب: دليل كامل

https://flutterdesk.com/how-to-make-responsive-flutter-app-a-complete-guide/

في منشور المدونة هذا، سنستكشف كيفية إنشاء تطبيق Flutter سريع الاستجابة ويتكيف بسلاسة مع الأجهزة المختلفة.


Drift — استخدام قاعدة بيانات SQLite مع Flutter

https://bettercoding.dev/drift-sqlite-database-flutter/

في هذا البرنامج التعليمي، ستتعلم كيفية إنشاء Drift واستخدامه فوق SQLite كقاعدة بيانات علائقية في Flutter.


إحياء charts_flutter: تقديم nimble_charts للوحات معلومات الويب الخاصة بك

https://www.christianfindlay.com/blog/reviving-charts-flutter/

يقدم المؤلف nimble_charts ، وهي مكتبة رسوم بيانية متجددة (charts_flutter) لـ Flutter والتي تم إعدادها لتحويل لوحات معلومات الويب الخاصة بك.

الجيد يجب ان يكون تصميم UX

قابل للاستخدام Usable

منصف Equitable

ممتع Enjoyable

مفيد Useful


هذه هي الخصائص الأساسية التي تجعل تصميم تجربة المستخدم (UX) جيداً. لنوضح كل منها بشكل بسيط:


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


2.منصف (Equitable): يجب أن يكون التصميم مناسباً لمختلف أنواع المستخدمين، بغض النظر عن خلفياتهم أو قدراتهم، بمعنى أن يكون شاملاً ومتاحاً للجميع.


3.ممتع (Enjoyable): تجربة استخدام المنتج يجب أن تكون ممتعة ومرضية، بحيث يشعر المستخدم بالراحة والسرور أثناء التفاعل معه، مما يزيد من احتمال استخدامه مرة أخرى.


4.مفيد (Useful): يجب أن يقدم المنتج فائدة حقيقية ويحل مشكلة أو يحقق حاجة محددة للمستخدم، مما يجعله ضروريًا ومهمًا بالنسبة لهم.


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

شرح مبسط وسريع figma ui/ux

↢ ماذ يعني تصميم واجهه الاستخدام UI

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

Figma هو أداة لتصميم واجهات المستخدم حيث يمكنك رسم الواجهات وتخطيطها ومشاركة التصاميم مع الآخرين بشكل تفاعلي. يسمح Figma للمصممين بإنشاء نماذج أولية للتطبيقات والمواقع الإلكترونية، مما يساعد المطورين على فهم الشكل النهائي للواجهة وتطبيقه في الكود البرمجي.

↢ ماذا يعني تصميم تجربة المستخدم UX

تصميم تجربة المستخدم (UX) هو عملية تصميم منتج أو خدمة بحيث يقدم تجربة إيجابية ومفيدة للمستخدمين. يتعلق ذلك بكيفية تفاعل المستخدم مع المنتج، ويشمل دراسة احتياجاتهم، وتحليل سلوكهم، وتصميم الحلول التي تجعل استخدام المنتج سهلاً وممتعاً.

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

↢ الفرق بين UX و UI:
  • UI (واجهة المستخدم) يركز على التصميم البصري، مثل الألوان والأيقونات والخطوط.
  • UX (تجربة المستخدم) يركز على كيفية عمل التطبيق والتفاعل معه بشكل كامل، بحيث يكون بسيطاً ومفهوماً وسريعاً.
↢ علاقه تصميم واجهات الايتحدام وتجربة المستخدم

تصميم واجهات المستخدم (UI) وتصميم تجربة المستخدم (UX) مرتبطان ببعضهما بشكل كبير، حيث يكمل كل منهما الآخر لتحقيق منتج ناجح وممتع للاستخدام. يمكن توضيح العلاقة بينهما كالتالي:

1. تصميم تجربة المستخدم (UX): يركز على التخطيط الكلي للتجربة، ويشمل كيفية تنظيم المحتوى، وسير العمل داخل التطبيق، وتحديد أهداف المستخدم واحتياجاته. بعبارة أخرى، يهتم بتوفير تجربة سهلة ومنطقية بحيث يتمكن المستخدم من إنجاز مهامه دون تعقيدات. يقوم مصمم تجربة المستخدم بإنشاء خرائط تدفق المستخدم (User Flows) وهياكل الأسلاك (Wireframes) لتوضيح كيفية عمل التطبيق وتفاعله.

2. تصميم واجهات المستخدم (UI): يركز على الجانب البصري والجمالي، أي الشكل الذي يراه المستخدم عند استخدام التطبيق. يشمل ذلك تصميم الأزرار، الألوان، الخطوط، الأيقونات، والتفاصيل التي تجعل التطبيق جذاباً وسهل الاستخدام. بعد أن يحدد مصمم تجربة المستخدم كيفية عمل التطبيق، يأتي دور مصمم الواجهة ليجعل هذه التجربة مرئية وملموسة.

↢ العلاقة بينهما:

  • تجربة المستخدم (UX) تهتم بـ "كيف يعمل التطبيق؟" و "ما الذي يجعل المستخدم يشعر بالراحة أثناء استخدامه؟".
  • واجهة المستخدم (UI) تهتم بـ "كيف يبدو التطبيق؟" و "ما الذي يجعل المستخدم يستمتع برؤية واستخدام الواجهة؟".
لذلك، لتحقيق منتج ناجح، يجب أن تكون تجربة المستخدم مصممة بشكل جيد ومتناسق مع واجهة المستخدم، بحيث تكون سهلة الاستخدام وجميلة المظهر في نفس الوقت.


↢ اهميه تصميم تجربه المستخدم وواجهه الاستخدام وللاعمال والمنتجات

تصميم تجربة المستخدم (UX) وواجهة المستخدم (UI) مهم جداً للأعمال والمنتجات لأنه يساعد في جذب المستخدمين وإبقائهم لفترة أطول. تصميم تجربة المستخدم الجيد يجعل المنتج سهلاً وممتعاً للاستخدام، مما يزيد من رضا العملاء وولائهم، بينما يساهم تصميم واجهة المستخدم الجذاب في جذب انتباه المستخدمين وتشجيعهم على التفاعل مع المنتج.

⇐ باختصار، تصميم UX/UI يساعد في:

  • زيادة المبيعات: تجربة مستخدم جيدة تشجع الناس على استخدام المنتج وشرائه.
  • رفع مستوى رضا العملاء: واجهة سهلة وجميلة تجعل المستخدمين سعداء وراضين.
  • بناء ولاء للعلامة التجارية: تجربة استخدام ممتازة تعزز الثقة وتجعل العملاء يعودون للمنتج مرة أخرى.
↢ ماذا احتاج كي اكون مصمم تجربه المستخدم وواجهه الاستخدام

لتصبح مصمم تجربة المستخدم وواجهة المستخدم (UX/UI)، تحتاج إلى اكتساب مجموعة من المهارات والمعرفة في مجالات مختلفة. إليك بعض الخطوات التي يمكن أن تساعدك:

1.تعلم الأساسيات:
  • مبادئ التصميم: فهم أساسيات التصميم مثل التوازن، الألوان، التباين، والتسلسل الهرمي.
  • تصميم تجربة المستخدم (UX): تعلم كيفية تحليل احتياجات المستخدمين، وإنشاء خرائط التدفق، والنماذج الأولية، وتجربة التصميم.
2.استخدام أدوات التصميم:

  • تعلم كيفية استخدام أدوات التصميم الشهيرة مثل Figma، Sketch وغيرها لتصميم واجهات المستخدم والنماذج الأولية.
3.تحليل سلوك المستخدم:

  • فهم كيفية البحث عن المستخدمين واختبار التصاميم بناءً على تجاربهم الفعلية.
4.مهارات التواصل:

  • القدرة على توصيل الأفكار والتصاميم بشكل فعال مع فريق العمل والعملاء.

5.الاطلاع على أفضل الممارسات:

  • متابعة تصاميم التطبيقات والمواقع الشهيرة، ومعرفة أحدث الاتجاهات في تصميم UX/UI.

6.التدريب والممارسة:

  • تنفيذ مشاريع صغيرة أو تجريبية لتحسين مهاراتك، مثل إعادة تصميم واجهات لتطبيقات موجودة أو إنشاء نماذج أولية لأفكار جديدة.
من خلال تطوير هذه المهارات، ستتمكن من بناء أساس قوي لتصبح مصمم UX/UI محترف.

⚠️ فكر مرتين قبل أن تطلب من الـChatGPT كتابة رسالة البريد الإلكتروني لك

إذا كنت تستخدم ChatGPT في عملك، فمن 

المحتمل أنك لاحظت مدى فائدته .

سواء كان كتابة البريد الإلكتروني الغريب أو تحليل جدول بيانات أو توليد الأفكار، يمكن أن توفر لك أداة الذكاء الاصطناعي هذه الوقت والجهد .

ولكن، مثل أي أداة قوية، تأتي بمخاطرها الخاصة .

أحد الشواغل الكبيرة هو كيف يتعلم ChatGPT من البيانات المقدمة .


دعنا نتعمق في سبب أهمية هذا وما تحتاج إلى الانتباه إليه .


💡فوائد استخدام ChatGPT


أولا، دعنا نتحدث عن الأشياء الجيدة .

يمكن لـ ChatGPT:

✔️ كتابة رسائل البريد الإلكتروني: هل تحتاج إلى إرسال ملاحظة سريعة أو بريد إلكتروني للمتابعة؟ يمكن لـ ChatGPT صياغته لك في ثوان .

✔️ تحليل البيانات: هل لديك جدول بيانات يحتاج إلى الفرز أو التحليل؟ يمكن أن يساعد ChatGPT في فهم أرقامك .

✔️ توليد الأفكار: عالق في جلسة العصف الذهني؟ يمكن أن يقدم ChatGPT أفكارا ووجهات نظر جديدة .


هذه مجرد طرق قليلة يمكن لـ ChatGPT أن تجعل مهامك اليومية أسهل .


⚠️ الخطر الكبير : حساسية البيانات


يتعلم ChatGPT من البيانات التي يعالجها .

هذا يعني أن لصق المعلومات الحساسة فيها أمر محفوف بالمخاطر .

تخيل كتابة خوارزمية سرية لشركتك أو بيانات العملاء الطبية أو غيرها من المعلومات السرية .

من المحتمل استخدام هذه البيانات لتدريب الذكاء الاصطناعي، مما قد يكون له آثار خطيرة .


ماذا يعني "التدريب"؟


عندما نقول إن ChatGPT "يتدرب" على البيانات، فإننا نعني أنه يتعلم من المدخلات التي يتلقاها لتحسين استجاباته.

كلما حصلت على المزيد من البيانات، كلما كان ذلك أفضل في إنشاء إجابات ذات صلة ودقيقة .

ومع ذلك، فإن هذا يعني أيضا أن أي معلومات حساسة مقدمة يمكن أن تكون جزءا من عملية التعلم هذه .


💡💭 فكر قبل أن تلصق بياناتك


قبل لصق هذا الجزء المهم من المعلومات في ChatGPT، اسأل نفسك :

✔️ هل هذه البيانات سرية؟ إذا كانت الإجابة بنعم، فكر مرتين .

✔️ هل يمكن لهذه المعلومات أن تضر بعملي إذا تم تسريبها؟ إذا كانت الإجابة بنعم، فمن الأفضل عدم مشاركتها .

✔️ هل ستكون مرتاحا لوجود هذه المعلومات في المجال العام؟ إذا لم يكن الأمر كذلك، فأبقه بعيدا عن ChatGPT .


نصائح عملية للبقاء آمنا


إليك بعض النصائح البسيطة لمساعدتك في استخدام ChatGPT بأمان .

* تجنب البيانات الحساسة .

لا تقم بإدخال معلومات تجارية شخصية أو طبية أو مالية أو خاصة حساسة .

* استخدم بيانات مجهولة المصدر. 

إذا كنت بحاجة إلى استخدام بيانات حقيقية، فتأكد من أنها مجهولة الهوية .

قم بإزالة الأسماء والعناوين وأي تفاصيل تعريف أخرى .

* راجع سياسات الخصوصية .

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

* قم بتدريب فريقك .

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


🗓️ الخلاصة: استخدم بحكمة، ابق آمنا


يمكن أن يكون ChatGPT مساعدا رائعا، ولكن تذكر: مع القوة العظيمة تأتي مسؤولية كبيرة .

من خلال مراعاة البيانات التي تشاركها واتخاذ خطوات لحماية المعلومات الحساسة، يمكنك الاستمتاع بفوائد ChatGPT مع الحفاظ على أمان عملك .


ثورة في التواصل: جيميني يرتقي بتجربتك على واتساب إلى آفاق جديدة

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


أبرز الميزات الجديدة

كتابة الرسائل تلقائيًا:

  • استخدام جيميناي لكتابة رسائل احترافية وجذابة نيابة عن المستخدم.
  • اقتراح ردود سريعة على الرسائل الواردة.
  • ترجمة الرسائل إلى لغات مختلفة.
  • التذكير بالمواعيد والمهام:
  • إضافة مواعيد وتذكير مباشرة في المحادثات.
  • تلقي تنبيهات قبل المواعيد الهامة.
  • إدارة المهام اليومية بسهولة.


البحث في المحادثات:

  • البحث السريع عن رسائل معينة أو ملفات تم مشاركتها.
  • تنظيم المحادثات وتصنيفها حسب الموضوع.
  • التكامل مع تطبيقات جوجل الأخرى:
  • الوصول إلى خدمات جوجل الأخرى مثل Google Calendar و Google Maps مباشرة من خلال واتساب.
  • حجز المطاعم أو الفنادق أو طلب سيارات الأجرة.

تحسين تجربة المستخدم:

  • اقتراح جهات الاتصال المناسبة أثناء كتابة الرسائل.
  • تلخيص المحادثات الطويلة.
  • توفير اقتراحات لملصقات وصور متحركة.

لتفعيل الميزه يجب ان يكون لديك احدث نسخه من وتساب وجيميني


خاتمة:


"يعد تكامل جيميناي مع واتساب خطوة مهمة نحو مستقبل حيث تصبح التكنولوجيا جزءًا لا يتجزأ من حياتنا اليومية بفضل هذا التكامل أصبح بإمكاننا إنجاز المزيد في وقت أقل وتحسين التواصل مع الآخرين هل أنت مستعد لتجربة هذه الميزة الرائعة؟"

كيفية اكتشاف ما إذا كان تطبيق Flutter موجودًا في الخلفية

في Flutter، توجد طرق متعددة للكشف عما إذا كان التطبيق في الخلفية أم في المقدمة. يتيح لك اكتشاف هذه الحالات تنفيذ إجراءات محددة بناءً على ما إذا كان التطبيق قيد الاستخدام النشط (في المقدمة) أو غير مرئي ولا يتلقى إدخال المستخدم (في الخلفية). في هذا المنشور، سنغطي طريقتين لتحديد ما إذا كان التطبيق في الخلفية أم في المقدمة.

استخدم WidgetsBindingObserver

النهج الأول هو استخدام WidgetsBindingObserverالفئة للكشف عما إذا كان تطبيق Flutter في الخلفية أم في المقدمة. يمكن لهذه الفئة ملاحظة التغييرات في دورة حياة التطبيق من خلال didChangeAppLifecycleStateالطريقة، التي توفر الوصول إلى AppLifecycleState.

يمكن استخدام الفئة WidgetsBindingObserverكمزيج باستخدام withالكلمة الأساسية. لذلك، سنقوم بإنشاء عنصر واجهة مستخدم جديد يسمى BackgroundDetectorيستخدم هذا المزيج.

كاشف الخلفية. دارت

(C)

import 'dart:ui';

import 'package:flutter/material.dart';

class BackgroundDetector extends StatefulWidget {
  const BackgroundDetector({
    required this.child,
    super.key,
  });

  final Widget child;

  @override
  State<BackgroundDetector> createState() => _BackgroundDetectorState();
}

class _BackgroundDetectorState extends State<BackgroundDetector>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) =>
      print('\x1B[34m $state \x1B[0m');

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

(C)

في مقتطف التعليمات البرمجية هذا، قمنا بإنشاء BackgroundDetectorعنصر واجهة مستخدم بحالة. _BackgroundDetectorStateتستخدم الفئة WidgetsBindingObserverالفئة كمزيج مع withالكلمة الأساسية.

في _BackgroundDetectorState، نتجاوز ثلاث وظائف: initStateو dispose، و didChangeAppLifecycleState.

تتوفر الدالتان and دائمًا للأدوات ذات الحالة. نستخدم الدالة initStateلإضافة المراقب والدالة لإزالته بمجرد التخلص من الأداة.disposeinitStatedispose

تم تجاوز الوظيفة didChangeAppLifecycleStateحتى نتمكن من الوصول إلى AppLifecycleState. يتم استدعاء هذه الطريقة كلما تغيرت حالة دورة حياة التطبيق. في الوقت الحالي، نقوم فقط بطباعة حالة دورة الحياة الحالية.

أخيرًا، BackgroundDetectorتتطلب الأداة childعنصر واجهة مستخدم سيتم إرجاعه.

في هذه didChangeAppLifecycleStateالوظيفة، تستخدم عبارة الطباعة أكواد الهروب ANSI لإضافة الألوان في واجهة سطر الأوامر. هذا التلوين مخصص لأغراض العرض التوضيحي فقط.


الرئيسية.دارت

 (C)

import 'package:application_in_background_demo/background_detector.dart';

import 'package:flutter/material.dart';


void main() => runApp(const BackgroundDetector(child: MyApp()));


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return const MaterialApp(

      home: Scaffold(),

    );

  }

}


(C)

في main.dartالملف، قمنا بتغليف MyAppالأداة باستخدام BackgroundDetectorالأداة الخاصة بنا. من خلال تغليف تطبيقنا بالكامل بالفئة BackgroundDetector، فسوف يتم دائمًا اكتشاف ما إذا كان التطبيق في الخلفية أم في المقدمة.

راجع ملف GIF أدناه لترى ذلك أثناء العمل. في واجهة سطر الأوامر، نقوم بطباعة حالة دورة حياة التطبيق الحالية في كل مرة تتغير فيها.


تغيير دالة DidChangeAppLifecycleState

بدلاً من طباعة كل شيء، AppLifecycleStateمن الأفضل تنفيذ الإجراءات على حالات معينة فقط. في هذه الحالة، سنغير الوظيفة didChangeAppLifecycleStateلتنفيذ الإجراء على الحالة resumedو فقط paused.

(C)

@override

void didChangeAppLifecycleState(AppLifecycleState state) {

  if (state == AppLifecycleState.resumed) {

    print('\x1B[34m App in foreground\x1B[0m');

  }


  if (state == AppLifecycleState.paused) {

    print('\x1B[33m App in background\x1B[0m');

  }

}

(C)


في مثال الكود هذا، نستخدم AppLifecycleStateالتعداد للكشف عما إذا كانت الحالة الحالية تساوي الحالة التي نريد التصرف بها. resumedتعني الحالة أن التطبيق موجود في المقدمة pausedوتعني الحالة أن التطبيق موجود في الخلفية.


إذا قمنا بتشغيل تطبيقنا مرة أخرى، ستلاحظ أننا الآن ننفذ الإجراءات على الحالة resumedو فقط paused.

الحالات المختلفة لـ AppLifecycleState Enum

حتى الآن، استخدمنا اثنين من الإدخالات الخمسة من AppLifecycleStateالتعداد، الذي يمثل الحالات المختلفة التي يمكن أن يوجد بها التطبيق. فيما يلي قائمة تشرح كل حالة:


  1. detached:يتم تشغيل التطبيق بدون شاشة مرئية في تلك اللحظة المحددة. إما أنه في عملية عرض شيء ما لأول مرة أو بعد إخفاء الشاشة مؤقتًا وقبل أن تصبح مرئية مرة أخرى.
  2. hidden:يتم إخفاء كافة وجهات نظر التطبيق.
  3. inactive:يتم إخفاء التطبيق جزئيًا بواسطة تطبيق آخر أو ورود مكالمة هاتفية. في هذه الحالة، قد يظل التطبيق مرئيًا ولكنه لا يتلقى إدخال المستخدم.
  4. paused:التطبيق موجود في الخلفية ولا يمكن للمستخدم رؤيته. قد يحدث ذلك عندما يقوم المستخدم بالتبديل إلى تطبيق آخر أو عندما ينتقل الجهاز إلى وضع السكون.
  5. resumed:التطبيق موجود في المقدمة ويمكن للمستخدم رؤيته. إنه الحالة النشطة حيث يمكن للمستخدم التفاعل مع التطبيق


باستخدام WidgetsBindingObserverclass و AppLifecycleStateenum، يمكنك بسهولة تتبع حالة دورة حياة التطبيق. ومع ذلك، هناك نهج بديل يمكنك اتباعه لمراقبة حالة دورة حياة التطبيق باستخدام حزمة Flutter FGBG.

إشعار بحدث المقدمة/الخلفية في Flutter

النهج الثاني يستخدم حزمة Flutter FGBG لتحقيق وظائف مماثلة. وبينما WidgetsBindingObserverتتيح لك معرفة متى يصبح تطبيقك نشطًا أو غير نشط، فإنها تأخذ أيضًا في الاعتبار التغييرات في أجزاء أخرى من التطبيق، والتي قد تؤدي إلى ملاحظات غير صحيحة.

تركز حزمة Flutter FGBG فقط على تطبيقك وتلاحظ بدقة متى ينتقل إلى الخلفية أو المقدمة. وهي تفعل ذلك بشكل مختلف بالنسبة لنظامي التشغيل iOS وAndroid للتأكد من صحة الملاحظات.


تثبيت حزمة Flutter FGBG

للبدء في التنفيذ، نحتاج أولاً إلى تثبيت  حزمة  Flutter FGBG  في مشروعنا . يمكننا تثبيت الحزمة من خلال تنفيذ الأمر التالي داخل مشروعنا:

(C)

flutter pub add flutter_fgbg

(C)

بمجرد تنفيذ الأمر، تأكد من التحقق من ملفك pubspec.yamlبحثًا عن التبعيات المضافة. يجب أن ترى حزمة Flutter FGBG مضمنة في قسم التبعيات، مثل هذا:


(C)

dependencies:

  flutter_fgbg: ^0.3.0

(C)

تنفيذ فئة FGBGNotifier

توفر حزمة Flutter FGBG FGBGNotifierعنصر واجهة مستخدم يستخدم للاستماع إلى الأحداث في المقدمة والخلفية. عندما تتغير حالة دورة حياة التطبيق، onEventيتم تشغيل معاودة الاتصال. يتيح لنا هذا تنفيذ إجراءات محددة بناءً على الحالة الحالية للتطبيق.

(C)

import 'package:flutter/material.dart';

import 'package:flutter_fgbg/flutter_fgbg.dart';


void main() => runApp(

  FGBGNotifier(

    onEvent: (FGBGType type) => switch (type) {

      FGBGType.foreground => print('\x1B[34mApp in the foreground (FGBGNotifier)\x1B[0m'),

      FGBGType.background => print('\x1B[33mApp in the background (FGBGNotifier)\x1B[0m'),

    },

    child: const MyApp(),

  ),

);


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return const MaterialApp(

      home: Scaffold(),

    );

  }

}

(C)

في main.dartالملف المحدث، قمنا بتنفيذ FGBGNotifierعنصر واجهة المستخدم. يحتاج هذا العنصر إلى onEventخاصية، والتي تأخذ دالة استدعاء تتلقى قيمة من FGBGTypeالتعداد. يحتوي التعداد على قيمتين: foregroundو background.


داخل معاودة الاتصال، نستخدم ifعبارة بسيطة لطباعة رسائل مختلفة بناءً على النوع المستلم. بالإضافة إلى ذلك، FGBGNotifierتأخذ الأداة رمزًا child، وفي هذه الحالة، نضبط MyAppالأداة باعتبارها الطفل.


عندما نقوم بتشغيل التطبيق، سنحصل على نفس السلوك كما في النهج السابق. ومع ذلك، تعمل هذه الحزمة على تبسيط التنفيذ ولا تبلغ إلا عن الأحداث على https://pub.dev/packages/flutter_fgbg#why مستوى التطبيق .


تجاهل بعض الأفعال
تحتوي حزمة Flutter FGBG أيضًا على وظيفة إضافية يمكن استخدامها لتجاهل إجراءات معينة. إذا كنت تريد تجاهل وظيفة تضع التطبيق في الخلفية، فيمكنك تغليف الوظيفة بالوظيفة ignoreWhile.

(C)
FGBGEvents.ignoreWhile(() {
  // your function
});
(C)

خاتمة
يكتشف كلا النهجين بنجاح ما إذا كان التطبيق في الخلفية أم في المقدمة. يستخدم النهج الأول WidgetsBindingObserverو AppLifecycleStateلمراقبة سلوك التطبيق. النهج الثاني أبسط ويستخدم حزمة Flutter FGBG، التي توفر FGBGNotifierأداة لتتبع الأحداث في الخلفية والمقدمة.

القائمة النهائية لإضافات المتصفح لصائدي الثغرات browser extensions for bugs hunters

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


إن استخدام الأدوات المناسبة، وخاصة ملحقات المتصفح، يمكن أن يعزز من فعاليتك وكفاءتك .

فيما يلي قائمة بالملحقات الأساسية التي يجب أن يمتلكها كل صائد الثغرات البرمجية .


Wappalyzer:  أداة تحليل التكنولوجيا التي تحدد التقنيات المستخدمة في مواقع الويب، من CMS إلى مكتبات JavaScript .


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


https://chromewebstore.google.com/detail/whatruns/cmkdbmfndkfgebldhnkbfhlneefdaaip


Hackbar:  ملحق للمتصفح لاختبار الاختراق، متوفر لمتصفحي Chrome وFirefox


https://addons.mozilla.org/en-US/firefox/addon/hackbar-free/versions/


FoxyProxy :  قياسي قم بتبسيط الوصول إلى خادم الوكيل في المتصفحات باستخدام القواعد وخيارات التبديل السريع


https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-standard/


مجموعة اختبار الاختراق OWASP : قم بتبسيط أمان التطبيق باستخدام فحص DAST وSCA داخل المتصفح بحثًا عن الثغرات الأمنية


https://chromewebstore.google.com/detail/owasp-penetration-testing/ojkchikaholjmcnefhjlbohackpeeknd


KNOXSS Community Edition: أداة لاكتشاف 

XSS (Cross-Site Scripting)


https://addons.mozilla.org/ar/firefox/addon/knoxss-community-edition/


Retire.js:  فحص تطبيقات الويب بحثًا عن مكتبات JavaScript المعرضة للخطر وتحديد الإصدارات القديمة


https://addons.mozilla.org/en-US/firefox/addon/retire-js/


Trufflehog:  ملحق للكشف التلقائي عن مفاتيح API وبيانات الاعتماد على مواقع الويب


https://addons.mozilla.org/en-US/firefox/addon/trufflehog/


DotGit:  اكتشاف أدلة .git المعرضة للخطر وغيرها من الثغرات الأمنية في مواقع الويب التي تمت زيارتها.


https://addons.mozilla.org/ar/firefox/addon/dotgit/


Bishop Vulnerability Scanner فحص الخلفية لأنظمة التحكم في الإصدار المكشوفة وأدوات الإدارة التي تم تكوينها بشكل غير صحيح


https://chromewebstore.google.com/detail/bishop-vulnerability-scan/cbkdeoaaclnbidadjimofnhpbfhjakoe


Modheader: تعديل رؤوس HTTP ورؤوس الاستجابة وعناوين URL باستخدام الخيارات المتقدمة لمتصفحي Chrome و Firefox


https://addons.mozilla.org/en-US/firefox/addon/modify-header-value/


HackTools:  تسهيل اختبارات اختراق تطبيقات الويب باستخدام أوراق الغش والأدوات مثل حمولات XSS والأصداف العكسية


https://addons.mozilla.org/en-US/firefox/addon/hacktools/


Request Maker : التقاط وتعديل وإرسال طلبات HTTP لاختبار الاختراق والتحليل


https://addons.mozilla.org/en-US/firefox/addon/http-request-maker/


 Shodan:  ابحث عن مكان استضافة مواقع الويب، ومالكي IP، والخدمات/المنافذ المفتوحة


https://addons.mozilla.org/en-US/firefox/addon/shodan-addon/


Open Multiple URLs  افتح صفحات ويب متعددة في علامات تبويب جديدة من قائمة نصية عادية


https://chromewebstore.google.com/detail/open-multiple-urls/oifijhaokejakekmnjmphonojcfkpbbh?hl=ar


Cookie-Editor  إنشاء ملفات تعريف الارتباط وتحريرها وحذفها للعلامة التبويب الحالية، وهو مثالي للخصوصية والتطوير


https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/


Mitaka : ابحث عن عنوان IP والنطاق وعنوان URL والهاش والمزيد عبر قائمة السياق باستخدام امتداد المتصفح هذا


https://addons.mozilla.org/en-US/firefox/addon/mitaka/


 D3coder: ملحق لترميز وفك تشفير النص باستخدام base64 وrot13 والمزيد


https://addons.mozilla.org/en-US/firefox/addon/encoder-decoder/


Redirect Path:  يتتبع عمليات إعادة توجيه HTTP للكشف عن مسارات إعادة التوجيه غير الآمنة وأكواد الحالة


https://addons.mozilla.org/en-US/firefox/addon/redirect-url-path/

كيفية عرض مقاطع فيديو YouTube في Flutter

يعد عرض مقاطع فيديو YouTube في تطبيق Flutter أمرًا سهلاً باستخدام المكون الإضافي المناسب. في هذا المنشور، ستتعلم كيفية استخدام مكون Youtube Player Flutter الإضافي لإضافة مقاطع فيديو YouTube إلى تطبيقك. سنغطي كل ما تحتاج إلى معرفته، من الإعداد والتخصيص إلى معالجة المشكلات الشائعة مع المكون الإضافي.

إضافة Flutter لمشغل YouTube


لبدء عرض مقاطع فيديو YouTube في Flutter، نحتاج أولاً إلى تثبيت  مكون https://pub.dev/packages/youtube_player_flutter Youtube Player Flutter  في مشروعنا. يتيح هذا المكون الإضافي البث المباشر لمقاطع فيديو YouTube ويستخدم واجهة برمجة تطبيقات مشغل IFrame الرسمية الخاصة بـ YouTube https://developers.google.com/youtube/iframe_api_reference?hl=ar . وهو متوافق مع كل من منصتي Android وiOS.

تثبيت البرنامج الإضافي Youtube Player Flutter
يمكننا تثبيت البرنامج الإضافي عن طريق تنفيذ الأمر التالي داخل مشروعنا:
<C>
flutter pub add youtube_player_flutter:^8.1.2
<C>

السبب الذي يجعلنا نحدد إصدارًا محددًا هو أن الإصدار الأحدث https://pub.dev/packages/youtube_player_flutter/versions/9.0.2 ، وقت كتابة هذا التقرير، يحتوي على خطأ https://github.com/sarbagyastha/youtube_player_flutter/issues/955 يتسبب في ظهور شريط تحميل بشكل مستمر في الفيديو.

الرئيسية.دارت

<C>

dependencies:

  youtube_player_flutter: ^8.1.2

<C>


تنفيذ البرنامج الإضافي لمشغل اليوتيوب

لتنفيذ مكون Youtube Player Flutter، سنقوم بإنشاء YoutubePageعنصر واجهة مستخدم في ملف Dart منفصل باسم . سيتم بعد ذلك عرض youtube_page.dartهذا العنصر باستخدام سمة العنصر في الملف.YoutubePagehomeMaterialAppmain.dart

<C>

import 'package:flutter/material.dart';

import 'package:youtube_videos_demo/youtube_page.dart';


void main() => runApp(const MyApp());


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return const MaterialApp(

      home: YoutubePage(),

    );

  }

}

<C>

في main.dartالملف، نقوم بإرجاع عنصر واجهة المستخدم الخاص بالتطبيق MaterialApp. داخل MaterialAppعنصر واجهة المستخدم، نستخدم homeالسمة لعرض YoutubePageعنصر واجهة المستخدم.


صفحة اليوتيوب.دارت

<C>
import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

class YoutubePage extends StatefulWidget {
  const YoutubePage({super.key});

  @override
  State<YoutubePage> createState() => _YoutubePageState();
}

class _YoutubePageState extends State<YoutubePage> {
  final YoutubePlayerController _controller = YoutubePlayerController(
    initialVideoId: 'PAOAjOR6K_Q',
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: YoutubePlayer(
          controller: _controller,
        ),
      ),
    );
  }
}
<C>

في youtube_page.dartالملف، نبدأ بإنشاء عنصر واجهة مستخدم بحالة. داخل حالة العنصر، نقوم بتعريف _controllerمتغير خاص يحمل مثيلًا لـ YoutubePlayerController. في هذه الحالة، نقوم بتعيين initialVideoIdالسمة إلى معرف الفيديو الذي نريد عرضه. أخيرًا، نقوم بإرجاع عنصر YoutubePlayerواجهة مستخدم، مع تعيين _controllerالمتغير إلى controllerسماته.

يمكنك بسهولة العثور على معرف الفيديو في عنوان URL لمقطع فيديو YouTube الذي تريد عرضه. يقع المعرف بعد watch?v=عنوان URL. على سبيل المثال، في عنوان URL https://www.youtube.com/watch?v=PAOAjOR6K_Q، يكون معرف الفيديو هو PAOAjOR6K_Q.

كما هو موضح في لقطة الشاشة أعلاه، يمكننا عرض مقاطع فيديو YouTube في Flutter باستخدام قدر صغير فقط من التعليمات البرمجية.


تجنب تسربات الذاكرة

ولمنع تسرب الذاكرة، من الضروري التخلص من وحدة التحكم بشكل صحيح عندما لا تكون هناك حاجة إليها بعد الآن.

<C>

import 'package:flutter/material.dart';

import 'package:youtube_player_flutter/youtube_player_flutter.dart';


class YoutubePage extends StatefulWidget {

  const YoutubePage({super.key});


  @override

  State<YoutubePage> createState() => _YoutubePageState();

}


class _YoutubePageState extends State<YoutubePage> {

  final YoutubePlayerController _controller = YoutubePlayerController(

    initialVideoId: 'PAOAjOR6K_Q',

  );


  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }


  @override

  Widget build(BuildContext context) {

    return Scaffold(

      body: Center(

        child: YoutubePlayer(

          controller: _controller,

        ),

      ),

    );

  }

}

<C>

في مقتطف التعليمات البرمجية أعلاه، نتخلص من الدالة _controllerعن طريق استدعاء دالة disposeداخل disposeالدالة التي تم تجاوزها. عند استخدام disposeالدالة التي تم تجاوزها، تأكد دائمًا من استدعاء الدالة super.disposeالأخيرة.


إضافة YoutubePlayerFlags

بالإضافة إلى initialVideoIdسمة YoutubePlayerController، يمكننا أيضًا استخدام flagsالسمة. تتيح لنا هذه السمة تعيين مثيل للفئة YoutubePlayerFlagsلتخصيص كيفية تصرف اللاعب.

<C>

final YoutubePlayerController _controller = YoutubePlayerController(

  initialVideoId: 'PAOAjOR6K_Q',

  flags: const YoutubePlayerFlags(

    forceHD: true,

    endAt: 20,

    enableCaption: false,

    hideThumbnail: true,

  ),

);

<C>

في مقتطف التعليمات البرمجية هذا، أضفنا flagsالسمة إلى YoutubePlayerControllerمثيل المتغير _controller. على flagsالسمة، قمنا بتعيين مثيل للفئة YoutubePlayerFlagsوأضفنا أربع سمات لفرض الدقة العالية وإنهاء الفيديو بعد 20 ثانية وتعطيل التسميات التوضيحية وإخفاء الصورة المصغرة.

تخصيص الإجراءات السفلية والعلوية

داخل YoutubePlayer، يمكننا أيضًا تخصيص الإجراءات السفلية والعلوية. راجع المثال أدناه:

<C>

import 'package:flutter/material.dart';

import 'package:youtube_player_flutter/youtube_player_flutter.dart';


class YoutubePage extends StatefulWidget {

  const YoutubePage({super.key});


  @override

  State<YoutubePage> createState() => _YoutubePageState();

}


class _YoutubePageState extends State<YoutubePage> {

  final YoutubePlayerController _controller = YoutubePlayerController(

    initialVideoId: 'PAOAjOR6K_Q',

  );


  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }


  @override

  Widget build(BuildContext context) {

    return Scaffold(

      body: Center(

        child: YoutubePlayer(

          bottomActions: [

            const SizedBox(width: 14),

            CurrentPosition(),

            const SizedBox(width: 8),

            ProgressBar(

              isExpanded: true,

              colors: const ProgressBarColors(

                playedColor: Color(0xFFFF0000),

                handleColor: Color(0xFFFF0000),

                backgroundColor: Colors.grey,

              ),

            ),

            RemainingDuration(),

          ],

          controller: _controller,

          topActions: const [

            PlaybackSpeedButton(),

          ],

        ),

      ),

    );

  }

}

<C>

في مقتطف التعليمات البرمجية أعلاه، قمنا بتخصيص كل من الإجراءات السفلية والعلوية لعلامتي YoutubePlayer. بالنسبة للإجراءات السفلية، قمنا بتضمين CurrentPositionالمؤشر وعلامة ProgressBar, والمؤشر RemainingDuration. لقد استخدمنا SizedBoxعناصر واجهة المستخدم لإضافة مسافات بين هذه العناصر وضبطنا ProgressBarألوان عناصر واجهة المستخدم لتتوافق مع مشغل YouTube الأصلي.

تخصيص مشغل اليوتيوب

لمزيد من المرونة، يمكننا استخدام YoutubePlayerBuilderالفئة لتخصيص المشغل. يوفر هذا النهج تحكمًا أكبر في سلوك المشغل، وخاصةً عند دخوله أو خروجه من وضع ملء الشاشة.

<C>

import 'package:flutter/material.dart';

import 'package:youtube_player_flutter/youtube_player_flutter.dart';


class YoutubePage extends StatefulWidget {

  const YoutubePage({super.key});


  @override

  State<YoutubePage> createState() => _YoutubePageState();

}


class _YoutubePageState extends State<YoutubePage> {

  final YoutubePlayerController _controller = YoutubePlayerController(

    initialVideoId: 'PAOAjOR6K_Q',

  );


  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }


  @override

  Widget build(BuildContext context) {

    final size = MediaQuery.of(context).size;

    final width = size.width;

    final height = size.height;


    return Scaffold(

      body: Center(

        child: OrientationBuilder(

          builder: (BuildContext context, Orientation orientation) =>

              YoutubePlayerBuilder(

            builder: (BuildContext context, Widget player) => SizedBox(

              width: orientation == Orientation.landscape ? height : width,

              height: orientation == Orientation.landscape ? width : height,

              child: player,

            ),

            player: YoutubePlayer(

              controller: _controller,

            ),

            onExitFullScreen: () {},

            onEnterFullScreen: () {},

          ),

        ),

      ),

    );

  }

}

<C>

في مقتطف التعليمات البرمجية أعلاه، نستخدم OrientationBuilderالأداة لتحديد اتجاه الشاشة الحالي. داخل منشئها، نعيد YoutubePlayerBuilder، والتي تعيد بدورها SizedBoxأداة. يتم تعديل أبعاد الأداة SizedBoxبناءً على الاتجاه.


في YoutubePlayerBuilder، نقوم بتعريف player، والتي تأخذ مثيلًا من YoutubePlayerالفئة. لدينا أيضًا إمكانية الوصول إلى السمات onEnterFullScreenو onExitFullScreen، والتي يمكن استخدامها لتحريك الإجراءات عندما يدخل اللاعب إلى وضع ملء الشاشة أو يخرج منه. في القسم القادم ، سنناقش onExitFullScreenالسمة بمزيد من التفصيل، وخاصةً لمعالجة مشكلة في شريط التنقل في Android.

تغيير الصورة المصغرة

بالاستمرار في استخدام الكود من القسم السابق، ربما لاحظت أن الصورة المصغرة لا يتم عرضها بشكل صحيح عند إيقاف تشغيل الفيديو مؤقتًا، وخاصة في الوضع الأفقي. لحسن الحظ، يمكننا تخصيص الصورة المصغرة لمعالجة هذه المشكلة.

<C>

import 'package:flutter/material.dart';

import 'package:youtube_player_flutter/youtube_player_flutter.dart';


class YoutubePage extends StatefulWidget {

  const YoutubePage({super.key});


  @override

  State<YoutubePage> createState() => _YoutubePageState();

}


class _YoutubePageState extends State<YoutubePage> {

  final YoutubePlayerController _controller = YoutubePlayerController(

    initialVideoId: 'PAOAjOR6K_Q',

  );


  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }


  @override

  Widget build(BuildContext context) {

    final size = MediaQuery.of(context).size;

    final width = size.width;

    final height = size.height;


    return Scaffold(

      body: Center(

        child: OrientationBuilder(

          builder: (BuildContext context, Orientation orientation) =>

              YoutubePlayerBuilder(

            builder: (BuildContext context, Widget player) => SizedBox(

              width: orientation == Orientation.landscape ? height : width,

              height: orientation == Orientation.landscape ? width : height,

              child: player,

            ),

            player: YoutubePlayer(

              controller: _controller,

              thumbnail: ColoredBox(

                color: Colors.black,

                child: Image.network(

                  YoutubePlayer.getThumbnail(

                    videoId: _controller.metadata.videoId.isEmpty

                        ? _controller.initialVideoId

                        : _controller.metadata.videoId,

                  ),

                  fit: BoxFit.contain,

                  loadingBuilder: (_, child, progress) =>

                      progress == null ? child : Container(color: Colors.black),

                  errorBuilder: (context, _, __) => Image.network(

                    YoutubePlayer.getThumbnail(

                      videoId: _controller.metadata.videoId.isEmpty

                          ? _controller.initialVideoId

                          : _controller.metadata.videoId,

                      webp: false,

                    ),

                    fit: BoxFit.contain,

                    loadingBuilder: (_, child, progress) => progress == null

                        ? child

                        : Container(color: Colors.black),

                    errorBuilder: (context, _, __) => Container(),

                  ),

                ),

              ),

            ),

          ),

        ),

      ),

    );

  }

}

<C>

في مقتطف التعليمات البرمجية أعلاه، أضفنا thumbnailالسمة إلى YoutubePlayerالمثيل. thumbnailتقبل السمة عنصر واجهة مستخدم، وفي هذه الحالة، استخدمنا عنصر ColoredBoxواجهة مستخدم بخلفية سوداء. داخل ColoredBoxعنصر واجهة المستخدم، قمنا بتضمين عنصر Image.networkواجهة مستخدم لعرض الصورة المصغرة.


نقوم باسترجاع الصورة المصغرة باستخدام getThumbnailوظيفة الفئة YoutubePlayer. بالإضافة إلى ذلك، أضفنا بديلاً للحالات التي لا يمكن فيها تحميل الصورة المصغرة. في هذه المواقف، يتم عرض حاوية سوداء أثناء جلب الصورة المصغرة.

إصلاح المشكلات المتعلقة بشريط التنقل في Android بعد الخروج من وضع ملء الشاشة


في قسم تخصيص مشغل YouTube ، ناقشنا هذه onExitFullScreenالخاصية بإيجاز. في هذا القسم، ستتعلم كيفية استخدام هذه الخاصية لحل مشكلة محتملة عندما تريد أن يعرض تطبيقك شريط التنقل الخاص بنظام Android.

<C>
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

class YoutubePage extends StatefulWidget {
  const YoutubePage({super.key});

  @override
  State<YoutubePage> createState() => _YoutubePageState();
}

class _YoutubePageState extends State<YoutubePage> {
  final YoutubePlayerController _controller = YoutubePlayerController(
    initialVideoId: 'PAOAjOR6K_Q',
    flags: const YoutubePlayerFlags(
      forceHD: true,
    ),
  );

  Future<void> _onExitFullScreen() async {
    await SystemChrome.setPreferredOrientations([]);
    await SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.manual,
      overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom],
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    _onExitFullScreen();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final width = size.width;
    final height = size.height;

    return Scaffold(
      body: Center(
        child: OrientationBuilder(
          builder: (BuildContext context, Orientation orientation) =>
              YoutubePlayerBuilder(
            builder: (BuildContext context, Widget player) => SizedBox(
              width: orientation == Orientation.landscape ? width : height,
              height: orientation == Orientation.landscape ? width : height,
              child: player,
            ),
            player: YoutubePlayer(
              controller: _controller,
            ),
            onExitFullScreen: _onExitFullScreen,
          ),
        ),
      ),
    );
  }
}
<C>

في مقتطف التعليمات البرمجية أعلاه، أضفنا _onExitFullScreenوظيفة خاصة. يتم تشغيل هذه الوظيفة عندما يخرج المشغل من وضع ملء الشاشة. بشكل افتراضي، يخفي المكون الإضافي شريط التنقل في Android، ولكن يمكننا تجاوز هذا السلوك. نستخدم وظيفة setEnabledSystemUIModeالفصل SystemChromeلاستعادة شريط التنقل في Android. يمكنك ضبط المعلمات لتناسب احتياجات مشروعك.

حساب نسبة العرض إلى الارتفاع
YoutubePlayerتتضمن الفئة أيضًا سمة aspectRatio، والتي تكون افتراضيًا 16:9. ومع ذلك، لدينا خيار تجاوز هذه القيمة. في الكود التالي، نحسب نسبة العرض إلى الارتفاع المثلى باستخدام خوارزمية إقليدية https://sites.math.rutgers.edu/~greenfie/gs2004/euclid.html . تساعدنا هذه الخوارزمية في العثور على القاسم المشترك الأعظم https://insaneimpact.com/aspect-ratio-calculator/#:~:text=To%20calculate%20an%20aspect%20ratio,height%20divided%20by%20the%20GCF ، والذي نستخدمه بعد ذلك لتحديد أفضل نسبة عرض إلى ارتفاع بناءً على أبعاد جهاز المستخدم.

<C>
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

class YoutubePage extends StatefulWidget {
  const YoutubePage({super.key});

  @override
  State<YoutubePage> createState() => _YoutubePageState();
}

class _YoutubePageState extends State<YoutubePage> {
  final YoutubePlayerController _controller = YoutubePlayerController(
    initialVideoId: 'PAOAjOR6K_Q',
  );

  double _calculateAspectRatio(double width, double height) {
    final greatestCommonFactor = _calculateGreatestCommonFactor(width, height);

    if (greatestCommonFactor == 0.0) {
      return 16 / 9;
    }

    return (width / greatestCommonFactor) / (height / greatestCommonFactor);
  }

  double _calculateGreatestCommonFactor(double width, double height) {
    final size = [width, height];
    final lowest = size.reduce(min);
    final highest = size.reduce(max);

    var remainder = highest % lowest;
    var greatestCommonFactor = 0.0;

    while (remainder != 0) {
      if ((lowest % remainder) == 0) {
        greatestCommonFactor = remainder;
        break;
      }

      remainder = lowest % remainder;
    }

    return greatestCommonFactor.abs();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.sizeOf(context);
    final width = size.width;
    final height = size.height;

    return Scaffold(
      body: Center(
        child: OrientationBuilder(
          builder: (BuildContext context, Orientation orientation) =>
              YoutubePlayer(
            controller: _controller,
            aspectRatio: _calculateAspectRatio(
              orientation == Orientation.landscape ? height : width,
              orientation == Orientation.landscape ? width : height,
            ),
          ),
        ),
      ),
    );
  }
}

<C>

في مقتطف التعليمات البرمجية أعلاه، قدمنا ​​دالتين خاصتين لحساب نسبة العرض إلى الارتفاع. _calculateGreatestCommonFactorتحدد الدالة العامل المشترك الأعظم، بينما _calculateAspectRatioتستخدم الدالة هذه القيمة لحساب أفضل نسبة عرض إلى ارتفاع ممكنة بناءً على أبعاد الجهاز. _calculateAspectRatioثم يتم تعيين النتيجة من إلى aspectRatioالسمة لضبط نسبة العرض إلى الارتفاع وفقًا للاتجاه الحالي.

أثناء تطوير تطبيقي Your News https://yournews.app/ ، واجهت مشكلات تتعلق بنسبة العرض إلى الارتفاع. إذا واجهت مشكلات مماثلة، فقد تجد أن الشوكة التي أنشأتها مفيدة https://github.com/sarbagyastha/youtube_player_flutter/compare/develop%E2%80%A6TijnvandenEijnde:youtube_player_flutter:develop . وهي تستند إلى الإصدار 8.1.2 من البرنامج الإضافي Youtube Player Flutter.


الاستنتاجات
في هذه المقالة، تعلمت كيفية عرض مقاطع فيديو YouTube في Flutter. بدأنا بالتنفيذ الأساسي وناقشنا خيارات التخصيص المختلفة. أخيرًا، تناولنا بعض المشكلات الشائعة مع المكون الإضافي التي اكتشفتها أثناء استخدامه. آمل أن تجد هذه المقالة مفيدة. إذا كانت لديك أي أسئلة أو واجهتك مشكلات، فلا تتردد في ترك تعليق.