Abdulraheem Barghouthi

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

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

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

  • Days Won

    2

السُّمعة بالموقع

114 Excellent

2 متابعين

  1. حتى لو كان حسابك البنكي بالدولار سيتم التحويل للعملة المحلية لبلدك. المشكلة في التحويل المباشر لحسابك البنكي هي أن الpaypal لا تعرض لك أي تفاصيل عن أسعارها الخاصة بالتحويل بين العملات. أما في حال السحب لبطاقة الvisa يتم خصم 1% من المبلغ وطبعا يمكنك سحب المبلغ كما هو بالدولار وبدون تحويله.
  2. للأسف وسيلة سحب الأرباح المتاحة حالياً في موقع خمسات ومستقل هي PayPal فقط. يمكنك إنشاء حساب PayPal بدون أي مشاكل لكن للأسف يجب إختيار الدولة إسرائيل، أنا من فلسطين ولدي حساب PayPal وأقوم بسحب أرباحي إلى الـvisa card المتربطة بحسابي البنكي، يمكنك أيضاً سحب الأرباح مباشرة إلى حسابك البنكي الفلسطيني لكن للأسف لا يمكنك سحبه بالدولار بل سترغمك paypal على تحويل المبلغ إلى عملتك المحلية " شيقل " قبل تحويله لحسابك.
  3. حسب التوثيق الخاص بـflutter فإن رسالة الخطأ التي ترجع الرقم 3 تعني أن عملية طلب الإعلان تمت بنجاح لكن لا يوجد إعلانات مناسبة لعرضها. تحدث هذه المشكلة عادة لسببين: عدم إضافة وسيلة دفع في قسم المعلومات المالية، على سبيل المثال عدم إضافة visa card ليتم الدفع لك عن طريقها. إذا كان الحساب أو التطبيق حديث الإنشاء، تحتاج الإعلانات الحقيقية عادةً إلى 48 ساعة للظهور. بما أن الإعلانات التجريبية ظهرت بدون مشاكل والإعلانات الحقيقية أرجعت الخطأ رقم 3 فإن إعداداتك سليمة لكن تأكد من معلوماتك المالية وإنتظر يوماً أو يومين لتظهر الإعلانات.
  4. يمكنك إضافة بريد إلكتروني جديد للمشروع وتعيينه كمالك من خلال الخطوات التالية: نضغط على الاعدادات ومن ثم نختار users and permissions كما هو موضح في الصورة التالية: نضيف بريد إلكتروني جديد ونقوم بتعيينه كمالك من خلال إختيار Owner:
  5. الخطأ يفيد بأن العملية لا يمكن تنفيذها بسبب عدم وجود صلاحيات للقيام بذلك. تأكد من فتحك للبرنامج بصلاحيات مدير، يفضل أيضاً عدم حفظ البرنامج في مجلدات حساسة مثل C:\\ أو C:\\program files أرفق لك صورة لنتائج تشغيل الكود الخاص بك حيث أنه يعمل على أكمل وجه:
  6. المشكلة تحدث بسبب كتابتك للأكواد الخاصة بإتصال الـclient في داخل الـloop وبعد ذلك لم تقم بإغلاق الإتصال من خلال close. لحل المشكلة يرجى نقل الكود التالي في قسم الـclient إلى خارج الـwhile loop: Socket s=new Socket(host,port); PrintWriter output=new PrintWriter(s.getOutputStream()); BufferedReader insok = new BufferedReader(new InputStreamReader(s.getInputStream())); ليكون الكود الكامل لقسم الـclient كالتالي: public class TestClient{ public static void main(String args[]){ try{ String host=""+args[0]; int port=Integer.parseInt(args[1]); BufferedReader input=new BufferedReader(new InputStreamReader(System.in)); String lettura=input.readLine(); Socket s=new Socket(host,port); PrintWriter output=new PrintWriter(s.getOutputStream()); BufferedReader insok = new BufferedReader(new InputStreamReader(s.getInputStream())); while(!lettura.equals("good")){ output.println(lettura); output.flush(); String lettsock=insok.readLine(); System.out.println(lettsock); lettura=input.readLine(); } input.close(); } catch(Exception ex){ System.out.println(ex); System.exit(3); } } }
  7. بما أن الشهادة تحمل رقم فريد ويمكن التحقق من صحتها إلكترونياً عبر موقع الأكاديمية فبالتأكيد هذه الشهادة معتمدة عالمياً. يمكنك معرفة المزيد عن الموضوع بمراسلة قسم المساعدة من هنا.
  8. يمكنك إسكات تحذيرات وإلغاء تفعيل SSL عن طريق تعديل الـurl الخاصة بقاعدة البيانات وإضافة useSSL=false و autoReconnect=true حيث ستكون الـurl كالتالي: jdbc:mysql://localhost:2000?autoReconnect=true&useSSL=false
  9. سأضيف معلومة مهمة جداً: عند إنشاء Thread بإستخدام Runnable فإنه يمكن تشارك الـObject لكل الـthreads، عكس الطريقة الثانية التي تنشئ Object منفصل لكل thread. سأترك لك مثال موضح بالتعليقات لتفهم الأمر بشكل أفضل: class MyImplementedThread implements Runnable{ // الطريقة الأولى public int counter = 0; @Override public void run(){ counter++; // يتم زيادة العداد في كل مرة يتم تشغيل //thread System.out.println("implemented: "+counter); } } class MyThread extends Thread{ // الطريقة الثانية public int counter = 0; @Override public void run(){ counter++; System.out.println("MyTheread: "+counter); } } public class Main{ public static void main(String []args){ //الطريقة الأولى MyImplementedThread myImplementedThread = new MyImplementedThread(); /* ننشئ الكائن الذي ستشترك به كل الـ threads التي ستتبع الطريقة الأولى */ Thread implemented1 = new Thread(myImplementedThread); /* نعرف thread جديدة مع ارفاق الكائن الخاص بالطريقة الأولى */ implemented1.start(); // نبدأ عمل الـ //thread try{ Thread.sleep(1000); /* نقوم بإيقاف تشغيل مؤقت لمدة ثانية واحدة قبل متابعة إنشاءالـ threads الأخرى */ } catch(Exception e){ System.out.println(e.getMessage()); } Thread implemented2 = new Thread(myImplementedThread); implemented2.start(); try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } Thread implemented3 = new Thread(myImplementedThread); implemented3.start(); try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } //---------------------- //الطريقة الثانية MyThread myThread1 = new MyThread(); myThread1.start(); /* ننشئ thread منفصلة في كل مرة */ try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } MyThread myThread2 = new MyThread(); myThread2.start(); try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } MyThread myThread3 = new MyThread(); myThread3.start(); try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } } } لاحظ ناتج تنفيذ البرنامج: وهذا يدل على التشارك في الـObject في الطريقة الأولى حيث تم زيادة الـcounter بواحد من قبل كل thread بينما في الطريقة الثانية كل thread كان لها object خاص بها وبالتالي ظهر الرقم واحد بدون أي زيادة.
  10. لفهم سبب إستخدام Char Array بدلاً من String يجب علينا أولاً فهم الفرق بينهم: String: هو عبارة عن نوع بيانات غير قابل للتغير أي أن مجرد تعريفك لبيانات ستبقى موجودة في الذاكرة لحين مسحها من قبل الـGarbage Collection المسؤولة عن إدارة الذاكرة. عند قيامك بتعريف متغير من نوع String بحيث يحتوي على القيمة النصية "hello" سيتم حفظه في String constant pool، في حال قمت بتغيير قيمة المتغير إلى " hello 2 " سيتم أنشاء String جديد وإضافته للـ String constant pool، أي عند تغيير قيمة المتغير يتم إنشاء كائن جديد من نوع String ولا يتم تعديل نفس الكائن. الخلاصة: لا يمكن مسح البيانات من String بعد تعريفها بل ستبقى في الذاكرة لحين مسحها من قبل الـGarbage Collection. Char Array: هي عبارة عن نوع بيانات قابل للتغير عكس الـString، أي عند تغيير قيم مصفوفة ما فإن القيم السابقة سيتم مسحها ولا يمكن إرجاعها. إذاً ما المغزى من إستخدام Char Array ؟ يجب أخذ التدابير الأمنية عند التعامل مع كلمات المرور والحسابات البنكية وغيرها من الأمور الحساسة الأخرى، لو إستخدمنا String في التعامل مع هكذا معلومات فيستطيع المهاجم الذي وصل إلى الذاكرة الخاصة بالـJVM أن يستخرج هذه المعلومات الحساسة بينما لو تم إستخدام Char Array فالمهمة ستكون أصعب كثيراً لأننا سنقوم بتعديل قيمة عناصر الـArray إلى قيم وهمية بعد إنتهائنا منها وبالتالي سيحصل على كلمة مرور خاطئة.
  11. صحيح لن يكون هناك أي مشكلة طالما لم يقدم أي أحد شكوى. أفضل مثال على هذا الموضوع هو عندما تقوم بإعادة نشر محتوى قناة ما على اليوتيوب. لن يتم حذف المحتوى التي تنشره الا اذا تقدم صاحب المحتوى الاصلي بطلب ضدك.
  12. تحدث هذه المشكلة بسبب إرفاقك للـcontext الذي قام بإنشاء الـscaffold بدلاً من إرفاق context ضمن الـscaffold. يمكن حل المشكلة من خلال إحدى الطرق التالية: الطريقة الأولى: إضافة Builder بحيث يعطينا context ضمن الـscaffold ومن ثم نقوم بإرفاقه للـ scaffold.of: body: Builder( Builder: (context){ //نضع هنا كل العناصر المراد عرضها لتأخذ الـ //context //الخاص بالـ //scaffold } ); إليك الكود الكامل بعد التعديل: import 'package:flutter/material.dart'; void main() => runApp(MyHomePage()); class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'test', theme: ThemeData( primarySwatch: Colors.cyan, ), home: Page1(), ); } } class Page1 extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('page1'), ), body:Builder( builder: (context) => Center( //*** child: RaisedButton( color: Colors.cyan, textColor: Colors.white, onPressed: (){ Scaffold.of(context).showSnackBar(SnackBar(content: Text('Hey there'))); }, child: Text('show snackbar'), ), ) ), ); } } الطريقة الثانية: حفظ الـscaffold في GlobalKey الذي سيلزمنا في إظهار الـsnackbar. class Page1 extends StatelessWidget { final GlobalKey<ScaffoldState> _myScaffold = new GlobalKey(); //… } بعد تعريف GlobalKey نقوم بتعيينه في خصائص الـScaffold: Scaffold( key: _myScaffold, //... ); الآن يمكننا إظهار الـsnackbar بدون الحاجة للـcontext من خلال الـGlobalKey: _myScaffold.currentState.showSnackBar(SnackBar(content:Text('Hey there'),)); مرفق الكود الكامل بعد التعديل: import 'package:flutter/material.dart'; void main() => runApp(MyHomePage()); class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'test', theme: ThemeData( primarySwatch: Colors.cyan, ), home: Page1(), ); } } class Page1 extends StatelessWidget { final GlobalKey<ScaffoldState> _myScaffold = new GlobalKey(); @override Widget build(BuildContext context) { return Scaffold( key: _myScaffold, appBar: AppBar( title: Text('page1'), ), body:Center( child: RaisedButton( color: Colors.cyan, textColor: Colors.white, onPressed: (){ _myScaffold.currentState.showSnackBar(SnackBar(content:Text('Hey there'),)); }, child: Text('show snackbar'), ), ), ); } }
  13. يمكنك تشغيل كود بلغة java للاندرويد وبلغة swift للـIOS عن طريق الـmethod channels حيث تمكننا من إستدعاء دوال معرفة مسبقاً بلغة java وتلقي القيم المرجعة منها. لاحظ كيف يتم التواصل عبر الـchannels بين التطبيق والدوال الخاصة بالـandroid والـIOS. لنأخذ مثالاً لتنفيذ كود بلغة java على الاندرويد لجلب معلومات عن الجهاز: أولا يجب كتابة الكود الذي نريد استدعائه من خلال الـmethod channles، نذهب إلى الملف " MainActivity.java " الموجود في مجلد android/java حيث سيكون الملف كالتالي: import io.flutter.embedding.android.FlutterActivity; public class MainActivity extends FlutterActivity { } نقوم بإضافة التعديلات الموضحة في الكود التالي: import androidx.annotation.NonNull; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugin.common.MethodChannel; import android.os.Build; public class MainActivity extends FlutterActivity { private static final String CHANNEL = "com.myapp.getInfo"; // اسم القناة الخاصة بنا @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler( (call, result) -> { //سيتم تنفيذ الكود في الـ // main thread if (call.method.equals("getManufacturer")) { // التحقق من إسم الدالة التي تم إستدعائها في حال كانت مطابقة String manufacturer = Build.MANUFACTURER; // جلب إسم الشركة المصنعة result.success(manufacturer); // إرجاع القيمة ليتم إستخدامها من قبل التطبيق } } ); } } بعد تعريف قناة خاصة بنا وهي " com.myapp.getInfo " وتعريف إسم الإستدعاء " getManufacturer" يمكننا الآن إستدعاء تلك الوظائف بلغة dart لترجع لنا إسم الشركة المصنعة للهاتف. أولاً وقبل إستدعاء الدالة getManufacturer يجب تهيئة القناة الخاصة بنا كالتالي: import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; //... class _MyHomePageState extends State<MyHomePage> { static const platform = const MethodChannel('com.myapp.getInfo'); // تعريف القناة //... } //... ثم نستدعي الدالة getManufacturer ونخزن القيمة المرجعة منها في متغير: final String result = await platform.invokeMethod('getManufacturer'); // إستدعاء الدالة وتخزين القيمة المرجعة منها في متغير وبذلك نكون قد كتبنا كود بلغة java وقمنا بإستدعائه عن طريق الـmethod channels.
  14. لو وضعت stateless widgets في الـList واعطيتهم أرقام مباشرة كالتالي: List<Widget> myList = [ Text(‘1’), Text(‘2’) ]; لسار كل شيء كما تريد لكنك قمت بإستخدام stateful widgets بدون تعيين key لها وبالتالي لن يتم التعرف على التغيير الحاصل في الـList الخاصة بك. لكن لماذا تم التعرف على هذا التغير عندما تم إستخدام عناصر من نوع stateless ؟ لأن القيمة النصية للعنصر مرتبطة بالعنصر نفسه أي لا يوجد لها حالة كما هو الحال في stateful widgets الذي تحتفظ بالقيمة النصية في الحالة الخاصة بها. إذاً لحل المشكلة يجب إضافة key فريد لكل العناصر المراد التبديل بينها بحيث يتم التفريق بين تلك العناصر حسب الـkey. يجب أولا أن نهيئ الـ constructor الخاص بـ MyRandomWidget ليستقبل key ويقوم بتمريره للـsuper: class MyRandomWidget extends StatefulWidget { MyRandomWidget({Key key}) : super(key: key); //….باقي الكود } بعد تهيئة الـconstructor نقوم بتمرير UniqueKey (مفتاح فريد يتم توليده عشوائياً ) عند تعريف العناصر في داخل الـList ليصبح الكود كالتالي: List<Widget> tiles = [ MyRandomWidget(key: UniqueKey()), //إضافة معرف فريد للعنصر MyRandomWidget(key: UniqueKey()),//إضافة معرف فريد للعنصر ]; الآن وبعد إسناد معرف فريد لكل عنصر سيعمل كل شيء على يرام. مرفق الملف بعد التعديل. main.dart
  15. حسب سياسية الإستخدام الخاصة بموقع Pinterest فإنه لا يمتلك الصور التي يتم نشرها من قبل المستخدمين بل هي لمالك/ناشر الصور فقط. لإستخدام الصور في أي أغراض أُخرى يجب أخذ إذن مسبق من مالك حقوق النشر للصورة حيث يمكن أن يكون المستخدم الذي قام نشرها. في النهاية يمكنك نشر ما تريد إلا في حال تقدم أحد ما بطلب حذف الصورة الخاصة بك مع إثبات ملكيته لحقوق النشر الخاصة بالصورة.