لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 06/28/16 في كل الموقع
-
المشكلة ربما تكمن في عدم توافق تعريف الكارت مع نظام التشغيل سوف أقدم لك شرح مبسط أتمنى أن تصل به الى حل أولا : الدرايفر الأصلي الخاص بجهازك من هنا http://support.lenovo.com/us/fr/products/laptops-and-netbooks/lenovo-g-series-laptops/lenovo-g510-notebook?beta=false واختر على حسب النسخة المثبتة بجهازك اذا كانت 32 بت او 64 بت وحمل ثانيا: للتخلص من هذا المشكل قم بالدخول من السيف مود ثم ثبت ملف الرجيستري من المرفقات اذا لم يقم بالدخول قم بالضغط على ctrl+alt+suppr ثم اضغط على file ثم nouvelle tache أو new ونكتب العبارة explorer.exe وسوف يدخل بعد ذلك قم بتعطيل كارت الجرافيك من خصائص التعريفات وقم بتثبي الدرايفر الاصلي المذكور اعلاه كما لاتنسى تثبيت ملف الرجيستر blach.reg2 نقاط
-
يبدو العملاء السلبيون -على أقل تقدير- مجرد أشخاص مزعجين، أما على أسوأ تقدير فقد يجعلوك ترغب في الصراخ. وعليه فإن معرفة كيفية التعامل معهم (على أمل تجنبهم) هو جزء من نموك كمستقل. وعلى الرّغم من أن مواجهة هذه الشّريحة من العُملاء يدخل في إطار عملنا كمستقلين إلا أننا لا نمنح أنفسنا الوقت الكافي للتعمق في هذه الظاهرة. من هم العملاء السلبيون وما هي العلامات التي تميزهم؟ هل تكون قوى الظلام في الكون قد أرسلتهم سرًا لتنغيص حياتنا وتخريب خططنا كمستقلين؟ وهل من الضروري التعامل معهم خلال رحلتنا لجذب العملاء؟ دعنا نعرف المزيد عن هذا الموضوع وكيف يمكنك التعامل معهم دون أن تشعر أنه تتم معاملتك بطريقة سيئة. من هم العملاء السلبيون؟ إن الزبون الذي يستحق لقب العميل السّلبي (أو العميل غير الفعال) هو الذي يبدي اهتمامًا كبيرًا بشراء المنتج أو الخدمة، ولكن دائمًا لديه سبب لعدم اتخاذ قرار الشراء. على سبيل المثال أنا أطلق هذا اللقب على العملاء المحتملين الذين يطاردوني على الإنترنت، يمكنني تقريبا سماع أنفاسهم اللاهثة من خلال شاشة حاسبي وهم يتوسلون لي حتى أبدأ في محادثتهم، لكن عندما يحين الوقت للتفاوض على أجري فإنهم إما: يختفون فجأة. ينتحبون من أجل تخفيض السعر. يدخلون في عملية تأمل وتفكير لا تنتهي. لا شيء مما سبق سيقودني إلى تحقيق دخل أو الحصول على عمل فعلي، يهدر هؤلاء العملاء السلبيون وقتي وطاقتي الشخصية ومصادري الاحترافية إضافة إلى أنه يمكنني استثمار هذا الوقت المهدور في متابعة عملاء محتملين أو مشاريع بديلة. هل حدث معك شيء من هذا سابقًا؟ هل شعرت من قبل أنك مغفل لاعتقادك بأن هذا العميل السلبي كان يفكرّ في توظيفك بشكل جدي. هل شعرت من قبل بأن البساط سُحِبَ من تحت قدميك؟ وهل ترغب في معرفة كيفية تجنب مواجهة هذه المشاعر مرة أخرى؟ لماذا يعذبنا هؤلاء؟ حسنًا، هناك سر صغير: هذا صحيح، فعلى الأرجح لا يفكر العملاء غير الفعالين في البائع مطلقًا، فهم لديهم جداول أعمالهم الخاصة، وهناك العديد من الصفات المميزة لتصرفات العملاء غير الفعالين، فهم إما.. مشترون حسب السعر: يبحث هؤلاء ببساطة عن أرخص سعر ممكن، وذلك إما لأنهم بخلاء أو ميزانيتهم محدودة جدًا. مشترون لا يقدّرون قيمة الخدمة: انهم مستاؤون لاضطرارهم دفع المال مقابل منتجاتنا وخدماتنا، ويفضلون القيام بالعمل بأنفسهم بدلًا منا، لكنهم أذكياء كفاية لمعرفة أنهم غير مؤهلين للقيام بالعمل بأنفسهم (أو ليس لديهم الوقت لذلك). مشترون جاهلون: إنهم في الحقيقية لا يعرفون كم يجب أن ينفقوا عندما يطلبون منا تحديد السعر، أو أنهم بصراحة متخبطون في قراراتهم، إنهم لا يعرفون ماذا يريدون وخائفون للغاية من اتخاذ القرار الخاطئ لذا يصبحون عاجزين عن الاختيار. لكن أسوأ ما في النوع الأخير أنهم يميلون إلى إلقاء اللوم علينا بسبب افتقارهم القدرة على اتخاذ القرار. كم مرة بذلت كل ما في وسعك وأنت تحاول إثبات أنك الشخص المناسب لاحتياجاتهم ولكن دون جدوى؟ ما هو تأثيرهم على أعمالنا كمستقلين؟ هل بذلنا جهدًا كبيرًا في محاولة عقد صفقة مع هؤلاء العملاء غير الفعالين؟ حسنًا لكننا في نهاية المطاف لم ننفق أموالًا (غالبًا) للاستمتاع بطلباتهم عديمة المعنى، صحيح؟ في الحقيقة على الرغم من أننا لم نخسر أموالًا (إلا إذا كنت قد استثمرت في حملة بريدية)، ولكننا أيضًا لم نحقق مداخيل ويمكن أن نكون قد خسرنا المال بطرق أخرى منها: إعطائهم وقت استشارة مجاني يسمح لهم بسرقة أفكارنا. الفشل في وضع قيمة مالية لوقت الاستشارة، فهناك العديد من الناس المستعدون لدفع أجر مُقابل الاستشارة، حيث يمكن أن يشكل الدفع مقابل الساعة مصدر دخل متجدد لنشاطك كمُستقل. عدم استثمار الوقت في أشياء أخرى تؤدي إلى توليد الدخل. إرسال وسائط تسويق رقمية أو مادية إلى عملاء غير مهتمين. بالإضافة إلى أن الوقت المهدور له تأثير سلبي (وتأثير سام أحيانًا) على تقديرنا لأنفسنا كمستقلين ومقدمي خدمات. إن التخلص من هؤلاء العملاء يتطلب الكثير من الثقة والشجاعة، وفي حال كان لديك موظفون ومتعاقدون عندئذٍ يجب أن يكون لديك قدر أكبر من الثقة والقوة. هل نحتاج حقا إلى مسايرتهم؟ دعنا نتحدث عن فكرة سائدة في عالم الأعمال التجارية، لا سيما في البلدان التي تولي أهمية كبيرة لتقديم خدمة عملاء ممتازة بغض النظر عن التكاليف (مثل الولايات المتحدة). الفكرة السائدة هي أنه يجب أن يرحب البائع بكل الأسئلة، حتى بعد أن يظهر جليًا أن العميل غير مهتم بما نقدمه له. سيتساءل بعض القراء فيما إذا كانوا سيخلقون سمعة سيئة لأنفسهم (أو لعلامتهم التجارية) في حال تبنوا سياسة صارمة وتوقفوا عن التعامل مع العملاء غير الفعالين. الإجابة هي: يصبر العديد من البائعين على العملاء المحتملين السيئين بسبب الخوف، في حين أنهم يجب أن يخافوا على الفرص والوقت المهدور. إنه ليس خطأك إذا كان العميل المحتمل السيئ لا يلائمك، وليس ذنبك بالتأكيد إذا كان مفلسًا أو متردّدًا. لذا توقف عن تحميل نفسك المسؤولية حيال العملاء المحتملين السيئين الذين لا يتحوّلون إلى زبائن في نهاية المطاف. ولا تقلق ﻷنهم سيجدون بائع آخر يتعلقون به ويهدرون وقته بينما تكون أنت قد انتقلت للتعامل مع عملاء محتملين يقدرون وقتك وما تعرضه عليهم. كيف تخرجهم من قمع مبيعاتك (أو تجنب السماح لهم بدخوله) اقتبس Perry Marshal مقالة من كتابه "قاعدة 20/80 في المبيعات والتسويق" والتي نشرت مؤخرًا في مجلة Entrepreneur. تعدد هذه المقالة 5 طرق لتشخيص الصفات التي يجب أن تكون موجودة في العميل قبل إجراء عملية البيع. من خلال تعلم كيفية تشخيص العملاء ستصبح معتادًا غالبًا على الانتباه إلى الإشارات التي تخبرك فيما إذا كان العميل جاهزًا أو غير مستعد بعد لعملية الشراء. لكن في حال إذا لم تستطع التقاط أي إشارات مهمة لتشخيص العميل ووجدت نفسك متورطًا مع أحد مهدري الوقت يمكنك حينها اتباع نموذج رجل المبيعات Dennis Kucinski الذي وجد طريقة للتّخلص من أحد العملاء الذي أهدر وقته. حيث سأل هذا العميل الذي ظل يُحاول إقناعه لمدة 5 سنوات كاملة: حيث أنه -وبعد مُضي خمس سنوات كاملة- قرّر ‘دنيس’ أن الزّبون إما هو جاهز للشراء أو أنه لن يقرر الشّراء أبدًا بطبيعية الحال، لا يُفترض بك الانتظار ومُحاولة إقناع الزّبون المُحتمل طيلة 5 سنوات وبرأيي الشخصي لا يجب أن تسمح لفترة النّقاش مع العميل المُحتمل أن تتجاوز 5 أسابيع. لكن بغض النظر عن المدة التي ستحاول فيها إرضاء العميل المُحتمل، عليك أن تعرف بأنك مدين لنفسك ولنشاطك التجاري (وكذلك لموظفيك والمتعهدين) بالتوقف عن التعامل مع العملاء السلبيين. عليك معرفة أن ما يفعله العملاء السلبيون هو معاملة البائع بشكل سيء، لا تأخذ الأمر بشكل شخصي ولكن أيضًا لا تدعهم يتلاعبون بك. ترجمة وبتصرف للمقال Tire Kickers: How To Diagnose These Time And Soul Suckers لصاحبته Terri Scott.2 نقاط
-
يُعتبر التصميم الجرافيكي مجالًا واسعًا جدًّا، ومهمّة الحصول على وظيفة مصمّم جرافيك ليست بالسّهلة. فعملية الحصول على وظيفة على شبكة الإنترنت تتطلب، بالإضافة إلى المهارات التي يجب أن تكتسبها، سِمات شخصية كمقاومة الإجهاد، الإبداع، والحافز الذاتي. لكنّ الجزء العملي يُعتبر، وبشكل واضح، هو الجزء الأهمّ، وهو الذي يتمّ الحكم من خلالهِ حتّى قبل تقييم مهاراتك الشخصيّة. لذلك سنبدأ اليوم بسلسلة من المقالات التي تدور حول أساسيات التصميم الجرافيكي، وسنستعرض في هذا الجزء العناصر الأكثر شيوعًا في هذا المجال. إنّ وظيفة مصمّم الجرافيك الرئيسية هي تصميم عناصر مرئية يمكن استخدامها في شبكة الإنترنت أو لغرض الطباعة. كمثال على ذلك؛ مخططات المواقع (التي يتم تحويلها في أغلب الأحيان إلى مواقع حقيقية من قِبل مصممي المواقع)، الملصقات، الكُتيّبات، النشرات، أو الحملات الإعلانية (في كِلا من شبكة الإنترنت والواقع). توجد في المجموع ستّة عناصر خاصّة بالتصميم يجب أن تكون مُلمًّا بها: الخط، الشكل، اللون، الخامة، القيمة والمساحة. 1. الخط يتواجد الخط عادةً في كلّ تصميم، حتّى لو كان إطارًا مُصمَتًا بعرض 1 بكسل أو خطًّا منقّطًا بعرض 5 بكسل. تحتوي جميع مواقع الإنترنت على خطوط، لكن مع أسلوب التبسيط للحدّ الأدنى (يُعرف أيضًا بالتبسيطية أو التقليليةMinimalism ) الذي أصبح شائعًا في السنوات الأخيرة هنالك محاولة لمسح الخطوط من مخططات الصفحات، أو على الأقل تقليل استخدمها. يمكن أن تكون الخطوط طويلة، حمراء، مستقيمة، رفيعة، زرقاء، متقطّعة، قصيرة، سوداء، أو منحنية، لكن تندرج جميعها تحت نفس الفئة. تستخدم الخطوط في أغلب الأحيان لرسم الحدود بين أقسام التصميم، أو لتوجيه نظر المشاهد نحو وجهة معيّنة. تعمل الخطوط على خلق تأثيرات ووقوع بصريّة مختلفة. تجذب الخطوط السميكة، العريضة الانتباه بسبب قوّتها البصرّية، بينما يكون للخطوط الرفيعة تأثيرًا مختلفًا معاكسًا لذلك. كما إن الألوان لها وقعٌ أيضًا، فالألوان الداكنة تكون سهلة الرؤية وجذب الانتباه أكثر من الألوان الفاتحة أو الباهتة. وهذا ليس كلّ ما في الأمر. فنمط الخط يمكن أن يؤثّر أيضًا في طريقة رؤية المستخدم له. هذا النمط يمكن تحديده بسهولة خلال CSS، ويمكن أن يكون، من بين الأنماط الأخرى، مصمتًا، منقّطًا، ومتقطّعًا. الخطوط المصمتة لها تأثير مختلف عن تأثير الخطوط المنقّطة، لأنّ الأولى تكون بارزة بشكل أكبر. في أسلوب التبسيط للحد الأدنى الذي تحدّثنا عنه سابقًا يتمّ إما استخدام الخطوط المصمتة بشكل أقلّ أو استخدم الخطوط المنحنية بشكل أكبر لأنها تعطي مظهرًا حركيًّا وانسيابيًّا للتصميم، والذي يعتبر أيضًا هدف من أهداف هذا الأسلوب. وهذه الخطوط توحي بالطاقة، تُبقي المستخدم مهتمًّا، وإذا ما تمّ دمجها مع الرسوم الإيضاحية سيصبح لها قوة فعّالة أمام عين الإنسان. كانت للخطوط المصمتة شعبية كبيرة قبل سنوات عديدة لأنها تحدد أسلوب التصميم؛ متين، متماسك، ومنظّم. لكنّ مواقع الإنترنت تغيّرت في السنوات الماضية ولم يعُد هذا النمط ذو شعبية بعد الآن، خاصّةً في معارض الأعمال Portfolio التابعة للمصمّمين والصفحات الأخرى ذات الحاجة الكبيرة إلى اللمسة الشخصية. فصلت الخطوط بين العمودين، وهي ليست بالعريضة جدًّا. استُخدمت الخطوط المصمتة للفصل بين أجزاء مختلفة من الموقع. 2. الشكل الشكل، أو الهيئة، هو العنصر الثاني الأكثر استخدامًا في تصميم المواقع. وهو في الواقع عبارة عن خطوط مجموعة جنبًا إلى جنب بأشكال مختلفة. ما زالت الأشكال تحظى بشعبيّة، وسبب هذا يعود إلى الحاجة إلى إبراز شيء ما، والأشكال هي إحدى الطرق للقيام بذلك. قد تكون الأشكال دوائر، مربّعات، مستطيلات، مثلّثات، أو غيرها من الأشكال التجريدية، ومعظم التصاميم تحتوي على الأقل على واحد من هؤلاء. يتمّ استخدام العديد من هذه الأشكال في تصاميم التبسيط للحد الأدنى، لأنها في الغالب تقوم على أساس الرسوم الإيضاحية والمخطّطات. كما إنّ النمط القديم لتصميم المواقع تضمّن الأشكال أيضًا، لذلك بقيت ذات شعبيّة طوال الوقت، وعلى الأرجح ستستمرّ على هذا المنوال. الأشكال، حالها كحال الخطوط، مرتبطة بذهن الإنسان بطرق مختلفة. على سبيل المثال؛ الدوائر مرتبطة بالحركة والطبيعة، بينما يتم النظر إلى المربّعات على أنها تصاميم أساسية هيكلية. وكما هو الحال في الخطوط فإن لون، نمط، خلفية أو خامة الشكل يمكن أن تغيّر كلّيًّا الإدراك الحسّي للمُشاهد. في معرض الأعمال الخاصّ بفريد مايا أعلاه، تمّ استخدام الأشكال لإبراز الشعار والأعمال السابقة. 3. الخامات Textures لم تكن الخامات ذات شعبيّة منذ بضع سنواتِ مضت، لكنّها تميل إلى أن تصبح أكثر وأكثر استخدامًا. وقد حلّت محل (أو نافست، إذا استطعنا تسميتها منافسة) الخلفيات ذات اللون المفرد. قد تبدو الخامات شبيهة بالخلفيات ذات الألوان المصمتة، لكن عند معاينتها عن قرب، يمكن ملاحظة اختلافات صغيرة ولكنّها فعّالة. تتضمّن أنماط الخامات الورق، الحصى، الخرسانة، الطوب، الألياف، والعناصر الطبيعية، وما بين الألوان الباهتة أو الناعمة. ويمكن للخامات أيضًا أن تكون دقيقة أو بارزة، وأن تستخدم باعتدال أو بإسباغ؛ يمكنها أن تعمل مع أي شيء تقريبًا. من شأن الخامات أن تغيّر شكل الموقع كليّا حتّى وإن بدت غير مهمّة، فهي توفّر وقعًا بصَريًّا مختلفًا تمامًا. في معرض الأعمال الخاص بجيسون جوليان أعلاه، تم استخدام خامة ذات النمط البالي grunge. في هذه الصفحة تمّ استخدام خامة مختلفة عن الخامة في المثال الأول، تبدو هذه كدفتر رياضيات. 4. اللون قد يكون اللون هو العنصر الأكثر أهميّةً في التصميم لأنه يعطي التأثير البصري الأقوى في لمحة واحدة. اللون واضح ولا يحتاج إلى مهارات رسم أساسية لملاحظتها. فبينما تعني الخطوط والأشكال الشيء نفسه كما في الواقع، عدا المستويات الأكثر عمقًا، تعني الألوان الشيء نفسه بالضبط كما في الطبيعة. الألوان تخلق الأحاسيس؛ الأحمر هو العاطفة، الأزرق هو الهدوء، والأخضر هو الطبيعة. للألوان تأثيرٌ واضحٌ على عقولنا حتّى وإن لم نُدرك ذلك. تم إجراء الدّراسات حول هذا الموضوع، ووجِد أن الشخص الذي يعيش في بيئة حمراء يمتلك ضربات قلب ونبضًا أعلى من الشخص الذي يعيش في بيئة زرقاء. الدماغ البشري يرى ذلك ويؤثّر على بقية الجسد تِبَعًا لما يراه. لذلك من المهم معرفة نظرية الألوان، حيث لا يمكن للعديد من المصممين أن يدعوا أنفسهم بالخبراء في هذا المجال. أن تكون خبيرًا في الألوان هو الذي يصنع الفرق بين التصميم الجيّد والتصميم المذهل. لا نقول إنه يجب أن تعرف كل شيء، لكن معرفة كيفية عمل خصائص اللون معًا كالصبغة Hue، الإشباع Saturation، الظل Shade، المشيج Tint، الدرجة Tone، أو الصفاء Chroma لهو أمرٌ جوهريّ بالنسبة لمصمم الجرافيك. في موقع Feed Fever تم استخدام ألوان مختلفة للنصوص في محاولة لإبراز أهمية كل خط باختلاف دقيق. 5. القيمة لم نتحدّث عن القيمة Value في النقطة السابقة على الرغم من أنها مرتبطة بشكل وثيق بعنصر اللون، لأن القيمة هي أكثر عمومية وهي التي تحدّد كون التصميم داكِنًا أو فاتِحًا. كما أن القيمة لها تأثير على المزاج أيضًا، ولكن فقط في مستويات أعمق. إنّ فهمك لخصائص الألوان يأخذك إلى مستويات قريبة من الإتقان، ولكن معرفة عمل وتأثير القيمة يأخذك إلى مستويات أبعد من ذلك. التصاميم الفاتحة تعطي انطباعًا وشعورًا مختلفًا عن التصاميم الداكِنة، ولذلك تحتاج إلى عينيّ خبير لملاحظة الفرق واختيار الأفضل تبعًا لذلك. 6. المساحة للمساحات وطريقة استخدامها تأثيرٌ مهمٌّ جدًّا في التصميم. أصبحت "المساحات البيضاء" (تسمّى أيضًا المساحات السلبية) تستخدم بشكل واسع في الآونة الأخيرة، لأنها تسمح للعين بالقراءة بشكل أسهل. ولمن لا يعرف مصطلح "المساحة البيضاء"؛ لا نقصد هنا أنها مملوءة باللون الأبيض على وجه التحديد، ولكن كل مساحة ضمن التصميم مملوءة فقط بلون الخلفية. يمكنك رؤية العديد من الأمثلة أدناه لفهم أفضل لهذا المفهوم. إذا كان تصميم الصفحة يحتوي على العديد من المساحات السلبيّة فإن هذا يضفي إضاءةً وشعورًا منفتحًا. وبخلاف ذلك يصبح التصميم مبعثرًا وقديم الطراز. وبذلك يكون للمساحات تأثيرٌ مهمّ في الطريقة التي يُنظر بها إلى التصميم من قِبل العين البشريّة. المساحات في مقدمة عناصر التصميم المهمّة، حتّى وإن قلنا إن اللون قد يكون العنصر الأهم، لأن المساحات من السهل ملاحظتها من قِبل العين المبتدئة. كما يمكنها أن تحوّل التصميم لصالحك والحصول على أفضل النتائج لمخطط صفحتك. صفحة جوجل هي أبسط مثال على استخدام المساحات السلبيّة بكثرة. في موقع Site Inspire تمّ استخدام المساحات السلبيّة على الجوانب وجُمع بينها وبين فنون الطباعة المناسبة. الخلاصة كانت هذه هي العناصر الأساسية التي يجب على كل مصمّم جرافيك مبتدئ أن يعرفها. وبالاطلاع على هذه العناصر يمكنك أن تفكّر أكثر من وجهة نظر المستخدم وبالتالي تستطيع التصميم بأسلوب أفضل. لكن هذا ليس كلّ شيء، هنالك المزيد عن مبادئ التصميم سنتحدث عنها في مقالات قادمة -إن شاء الله-. ترجمة -وبتصرّف- للمقال: Graphic Design Basics Part 1: Elements لصاحبه: James Richman. حقوق الصورة البارزة: Designed by Freepik.1 نقطة
-
لدى برمجة تطبيقات أندرويد، فإنّه وفي العديد من الأحيان نحتاج أن نعرض مجموعة من العناصر معًا في النشاط أمام المستخدم كعرض جهات الاتصال مثلًا أو الرسائل حيث يمكن للمستخدم أن يتصفحها ويتنقل بينها سريعًا، كما يمكنه الضغط على أي منها فيتم عرض المزيد من المعلومات عن هذا العنصر. نستخدم عنصر الواجهة ListView أو قائمة العرض للقيام بما سبق والذي يتيح عرض أكثر من عنصر في قائمة واحدة، ويتم إضافة العناصر إلى قائمة العرض تلقائيًا باستخدام كائن من الصنف Adapter والذي يستطيع جلب المحتوى من مصفوفة من البيانات أو قاعدة بيانات. ويُعتبر الصنف Adapter بمثابة حلقة الوصل بين عنصر الواجهة الخاص بقائمة العرض ومصدر البيانات المستخدم حيث يقوم بتشكيلها بالشكل المطلوب لتُمثل عنصرًا من عناصر القائمة. يوجد عدة أصناف فرعية من الصنف Adapter كي تُستخدم مع أشكال البيانات المختلفة مثل: ArrayAdapter Base Adapter SimpleCursorAdapter قوائم العرض مع كائن من ArrayAdapter تطبيق 1 يُستخدم ArrayAdapter عندما يكون المصدر البيانات هو قائمة أو مصفوفة. سنقوم بصنع تطبيق يعرض مجموعة من النصوص في قائمة العرض، لذا سنقوم بعمل مشروع جديد في Android Studio. ولتكوين قائمة العرض نقوم بالخطوات التالية: نضع عنصر من ListView في ملفات الواجهة ونشير له بـ Id مميز، ثم نربط هذا العنصر بشيفرات الجافا باستخدام التابع ()findViewById. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listview"/> </LinearLayout> نصنع ملف واجهة جديد يكون الجذر له عنصر من النوع TextView. ولصنع واجهة استخدام جديدة نضغط على المجلد layout المتواجد داخل res بالزر الأيمن ثم نختار: new > XML > Layout XML File ونسميه row_item. وبداخل هذا الملف نجعل عنصر الجذر من النوع TextView ونغير حجم النص الذي سيُكتب بداخله إلى 20sp ونجعل الخاصية padding لها قيمة 20sp. لاحظ أن الخاصية padding تعني الحشو أي ضع فراغًا مقداره 20sp حول النص المكتوب داخل TextView في كل الاتجاهات. <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:textSize="20sp" android:padding="20sp"/> في شيفرة الجافا نبني كائنًا جديدًا من الصنف ArrayAdapter ونمرر لدالة البناء الخاصة به ثلاث عناصر: العنصر الأول هو this والذي يعبر عن السياق الخاص بالنشاط المكوّن للقائمة. العنصر الثاني هو TextView الذي سيُعرض فيه كل نص في القائمة. العنصر الأخير هو المصفوفة الخاصة بالنصوص التي سيتم عرضها في قائمة العرض. ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.row_item,colorsArray); نستدعي التابع ()setAdapter باستخدام الكائن الخاص بالـ ListView ونمرر له الـ Adapter الذي قمنا بصنعه ليصبح التطبيق النهائي: package apps.noby.listviewexample; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { private ListView lv; String [] colorsArray = {"Red","Yellow","Blue","Orange","Black","Green","Brown","Grey"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv =(ListView) findViewById(R.id.listview); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.row_item,colorsArray); lv.setAdapter(adapter); } } ثم نقوم بتجربة التطبيق على المحاكي لنتأكد من عمله بالشكل المطلوب. تطبيق 2 في هذا التطبيق بدلًا من استخدام المصفوفة لتخزين البيانات سنقوم باستبدالها بقائمة من النوع ArrayList مع الحفاظ على باقي ملفات الواجهة السابقة لتصبح الشفرة النهائية بعد التعديل: package apps.noby.listviewexample; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; import java.util.ArrayList; public class MainActivity extends Activity { private ListView lv; ArrayList<String> colorsList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); colorsList = new ArrayList<String>(); colorsList.add("Red"); colorsList.add("Yellow"); colorsList.add("Blue"); colorsList.add("Orange"); colorsList.add("Black"); colorsList.add("Green"); colorsList.add("Brown"); colorsList.add("Grey"); lv =(ListView) findViewById(R.id.listview); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.row_item,colorsList); lv.setAdapter(adapter); } } وبتجربة هذا التطبيق على المحاكي نجد أنه يقوم بنفس الوظيفة السابقة، ولكن استخدامنا للقائمة بدلًا من المصفوفة يتيح لنا القدرة على إضافة أو إزالة العناصر بسهولة وهو ما لا تسمح به المصفوفة. استجابة عناصر القائمة عند الضغط عليها تطبيق 3 سنقوم في هذا التطبيق بجعل العناصر المتواجدة بقائمة العرض تستجيب عند الضغط عليها، فكما ذكرنا سابقًا أننا استخدمنا كائنًا من نوع ArrayList لسهولة إضافة أو إزالة العناصر منه، سنقوم الآن بتطبيق هذا المفهوم حيث سنقوم بإزالة العنصر من القائمة عند الضغط عليه. كما نستخدم التابع ()setOnClickListener مع الزر للاستجابة عند الضغط عليه سنقوم هنا باستخدام التابع ()setOnItemClickListener للاستجابة عند الضغط على عناصر القائمة، وبداخله نجد الدالة ()onItemClick وبها العناصر التالية: parent وهو يُعبر عن الأب الخاص بالعنصر الذي تم الضغط عليه وفي هذا المثال فهو ListView. view ويُمثل العنصر نفسه الذي تم الضغط عليه أي TextView. position ويُعبر عن رقم العنصر في القائمة. Id وهو رقم مميز يتم تحديده لعنصر الواجهة الذي يعرض النص. لتصبح الشفرة النهائية الخاصة بهذا التطبيق: package apps.noby.listviewexample; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import java.util.ArrayList; public class MainActivity extends Activity { private ListView lv; ArrayList<String> colorsList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); colorsList = new ArrayList<String>(); colorsList.add("Red"); colorsList.add("Yellow"); colorsList.add("Blue"); colorsList.add("Orange"); colorsList.add("Black"); colorsList.add("Green"); colorsList.add("Brown"); colorsList.add("Grey"); lv =(ListView) findViewById(R.id.listview); final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.row_item,colorsList); lv.setAdapter(adapter); lv.setOnItemClickListener(new ListView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String item = (String) parent.getItemAtPosition(position); colorsList.remove(item); adapter.notifyDataSetChanged(); } }); } } بداخل التابع ()onItemClick نستخدم الكائن parent لاستدعاء التابع ()getItemAtPosition وتمرير رقم العنصر له حتى يُعيد لنا النص المخزن في ذلك العنصر. ثم بعد ذلك نقوم بإزالة العنصر من القائمة واستدعاء التابع ()notifyDataSetChanged باستخدام الكائن adapter وذلك لتنفيذ التغيير الذي حدث على عناصر قائمة العرض. الآن نقوم بتجربة التطبيق على المحاكي، نجد أنه عند الضغط على أحد العناصر تختفي في الحال. يمكنك تطوير هذا التطبيق لجعله يستدعي نشاطًا جديدًا عند الضغط على أحد العناصر. البحث داخل عناصر قائمة العرض تطبيق 4 في هذا التطبيق سنقوم بالبحث عن العناصر التي تحتوي على نص معين وعرضها هي فقط وذلك لسهولة الوصول لعنصر محدد. كتطوير على التطبيق السابق سنقوم بإضافة الخاصية Orientation للعنصر LinearLayout في ملف activity_main.xml. android:orientation="vertical" ثم نضيف عنصر EditText قبل ListView وهو العنصر الذي سيقوم المستخدم بالتفاعل معه وكتابة النص الذي سيبحث عنه داخل قائمة العرض. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableLeft="@drawable/ic_search_black_24dp" android:hint="Search..." android:id="@+id/searchedittext"/> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listview"/> </LinearLayout> ولإضافة صورة يسار العنصر EditText نستخدم الخاصية drawableLeft ثم نضيف الصورة من المجلد drawable. الآن سنربط هذا العنصر بالشيفرة الرئيسية للتطبيق ثم نستدعي التابع ()addTextChangedListener والذي يستجيب لأي تغير يحدث داخل EditText، حيث يوفر ثلاث دوال: searchET.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } @Override public void afterTextChanged(Editable s) { } }); كل دالة تختص بفترة محددة، وهنا نهتم بالدالة ()onTextChanged والتي يتم استدعاؤها لحظة تغير النص المكتوب بداخل EditText. أخيرًا لتنقية القائمة وترك فقط العناصر التي يتم البحث عنها نستدعي التابع ()getFilter باستخدام الكائن الخاص بالـ ArrayAdapter ثم نستدعي بعده مباشرة التابع ()filters ونمرر له المتغير s الذي يحمل بداخله النص الذي قمنا بكتابته في EditText. لتصبح الشيفرة النهائية كما يلي: package apps.noby.listviewexample; import android.app.Activity; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; import java.util.ArrayList; public class MainActivity extends Activity { private ListView lv; private ArrayList<String> colorsList; EditText searchET; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); colorsList = new ArrayList<String>(); colorsList.add("Red"); colorsList.add("Yellow"); colorsList.add("Blue"); colorsList.add("Orange"); colorsList.add("Black"); colorsList.add("Green"); colorsList.add("Brown"); colorsList.add("Grey"); searchET = (EditText) findViewById(R.id.searchedittext); lv =(ListView) findViewById(R.id.listview); final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.row_item,colorsList); lv.setAdapter(adapter); lv.setOnItemClickListener(new ListView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String item = (String) parent.getItemAtPosition(position); colorsList.remove(item); adapter.notifyDataSetChanged(); } }); searchET.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } @Override public void afterTextChanged(Editable s) { } }); } } بعد ذلك نقوم بتجربة التطبيق على المحاكي لنتأكد من عمله كما ينبغي. تخصيص واجهة قائمة العرض تطبيق 5 تُتيح قائمة العرض ميزة تخصيص العناصر، فيمكن صنع قائمة عرض تتكون من نص وصورة في كل صف بدلًا من نص فقط كالأمثلة السابقة. في هذا التطبيق سنقوم بصنع تطبيق يعرض قائمة كما في الصورة التالية، وعند الضغط على العنصر يعرض نشاطًا جديدًا. من Android Studio نقوم بعمل مشروع جديد، نبدأ أولًا بصنع واجهة المستخدم الرئيسية والمتكونة من ListView. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listview"/> </LinearLayout> نصنع ملف واجهة جديد يُعبر عن الصف ويدعى row_item وبداخله نكون الشكل المطلوب للصف في قائمة العرض كما في المخطط التالي: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/blue" android:id="@+id/imgview"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Title Example" android:textSize="20sp" android:textStyle="bold" android:id="@+id/titleview"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Description Example" android:textSize="15sp" android:id="@+id/descview"/> </LinearLayout> </LinearLayout> يتكون الصف في قائمة العرض من صورة، نص العنوان ونص الوصف لذا سنصنع صنفًا جديدًا يحتوي بداخله على هذه المعلومات الخاصة بالعنصر ثم نكوّن مصفوفة أو قائمة من هذه الصنف. لصنع صنفًا جديدًا من داخل المجلد java اضغط بالزر الأيمن على اسم الحزمة الخاصة بالمشروع واختر New > Java Class ثم اكتب اسم الصنف الجديد ListItem. بداخل هذا الصنف الجديد نعرّف ثلاث متغيرات، package apps.noby.customlistviewexample; public class ListItem { public int imgSrc; public String title; public String desc; } في ملف MainActivity.java نكتب الشيفرة الخاصة بالمشروع. أولًا نصنع كائنًا من الصنف ArrayList ليكون هو مصدر البيانات التي ستُعرض في قائمة العرض، ويتكون الكائن من مجموعة من الكائنات الأخرى من الصنف ListItem لكل منها صورة خاصة به، نص العنوان ونص الوصف. private ArrayList<ListItem> items; String [] colorsArray = {"Red","Yellow","Blue","Black","Green","Brown","Grey"}; int [] colorsImage = {R.drawable.red,R.drawable.yellow,R.drawable.blue,R.drawable.black,R.drawable.green,R.drawable.brown,R.drawable.grey}; items = new ArrayList<ListItem>(); for(int i=0;i<colorsArray.length;i++){ ListItem item= new ListItem(); item.imgSrc=colorsImage; item.title = colorsArray; item.desc = colorsArray + " Color!"; items.add(item); } ثانيًا بعد ذلك نصنع الكائن الخاص بالـ ArrayAdapter ولكننا لا يمكننا استخدام الصنف الأساسي من ArrayAdapter حيث أنه لا يعمل إلا مع نص واحد فقط ولن يمكننا تغيير الصورة أو النص الثاني، لذا ينبغي علينا صنع الصنف ArrayAdapter الخاص بنا. بنفس الطريقة السابقة نصنع صنف جديد من داخل المجلد Java، اضغط بالزر الأيمن على اسم الحزمة الخاصة بالمشروع واختر New > Java Class ثم اكتب اسم الصنف الجديد CustomArrayAdapter. يجب أن يرث هذا الصنف الفرعي من الصنف الأساسي ArrayAdapter. public class CustomArrayAdapter extends ArrayAdapter ثم نقوم بكتابة دالة البناء الخاصة بهذا الصنف ونستدعى في بدايتها دالة البناء الخاصة بالصنف الأب، وتحتاج دالة البناء لكائن من الصنف Context وهو السياق الذي سيعمل فيه هذا الـ Adapter أي النشاط الذي سيعمل به، كما يحتاج إلى واجهة المستخدم التي تكون شكل الصف، وقائمة البيانات التي سيتم عرضها. private Context con; private ArrayList<ListItem> data; private int resLayout; public CustomArrayAdapter(Context context, int resource, List objects) { super(context, resource,objects); con = context; resLayout = resource; data =(ArrayList) objects; } يوجد تابع داخل ArrayAdapter يُدعى ()getCount ويتم استخدامه بشكل تلقائي عندما يريد الكائن الذي سنصنعه من CustomArrayAdapter معرفة عدد العناصر التي سيقوم بعرضها داخل قائمة العرض، لذا فهو يستدعي التابع ()size باستخدام الكائن الخاص بالبيانات. @Override public int getCount() { return data.size(); } وبداخل الصنف الأب ArrayAdapter يوجد أيضًا تابع يُدعى ()getView، وهو المسؤول عن تكوين الشكل الخاص بالصف المعروض في قائمة العرض لذا كي نصنع الصف الخاص بنا يجب علينا تعديل هذا التابع. ولتعديل التابع نقوم بكتابته بطريقتنا الخاصة كما يلي: @Override public View getView(int position, View convertView, ViewGroup parent) { inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rootView = inflater.inflate(resLayout,null); ImageView img = (ImageView) rootView.findViewById(R.id.imgview); TextView title = (TextView) rootView.findViewById(R.id.titleview); TextView desc = (TextView) rootView.findViewById(R.id.descview); ListItem item = data.get(position); img.setImageResource(item.imgSrc); title.setText(item.title); desc.setText(item.desc); return rootView; } داخل التابع نبدأ أولًا بطلب الكائن LayoutInflater وهو المسؤول عن تحويل ملف XML إلى كائن من النوع View وللحصول عليه نستخدم التابع ()getSystemService والذي يوفر مجموعة مختلفة من الخدمات منها الكائن LayoutInflater، ويتم تحديد نوع الخدمة المطلوبة عن طريق تمرير ثابت محدد وفي هذه الحالة هو Context.LAYOUT_INFLATER_SERVICE. بعد الحصول على هذا الكائن نستدعي التابع ()inflate ونمرر له ملف XML الذي نرغب في تحويله إلى كائن في ملف الجافا. inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rootView = inflater.inflate(resLayout,null); الآن لربط عناصر الواجهة بالشيفرة نستخدم التابع ()findViewById ولكنا هنا لا نستطيع استخدامه مباشرة كما كنا نفعل عند وجودنا داخل شيفرة النشاط، لذا يجب أن نستدعي التابع باستخدام الكائن من الصنف View الذي حصلنا عليه من التابع ()inflate. ImageView img = (ImageView) rootView.findViewById(R.id.imgview); TextView title = (TextView) rootView.findViewById(R.id.titleview); TextView desc = (TextView) rootView.findViewById(R.id.descview); أخيرًا نأتي بالبيانات المناسبة للعنصر من داخل الـ ArrayList ثم نضع بداخل كل عنصر من عناصر الواجهة البيانات الخاصة به. ListItem item = data.get(position); img.setImageResource(item.imgSrc); title.setText(item.title); desc.setText(item.desc); لتصبح الشيفرة النهائية داخل الصنف CustomArrayAdapter: package apps.noby.customlistviewexample; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.List; public class CustomArrayAdapter extends ArrayAdapter { private Context con; private ArrayList<ListItem> data; private LayoutInflater inflater; private int resLayout; public CustomArrayAdapter(Context context, int resource, List objects) { super(context, resource,objects); con = context; data =(ArrayList) objects; resLayout = resource; } @Override public int getCount() { return data.size(); } @Override public View getView(int position, View convertView, ViewGroup parent) { inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rootView = inflater.inflate(resLayout,null); ImageView img = (ImageView) rootView.findViewById(R.id.imgview); TextView title = (TextView) rootView.findViewById(R.id.titleview); TextView desc = (TextView) rootView.findViewById(R.id.descview); ListItem item = data.get(position); img.setImageResource(item.imgSrc); title.setText(item.title); desc.setText(item.desc); return rootView; } } نعود مجددًا إلى ملف MainActivity.java لإنشاء كائن من الصنف الذي صنعناه: private CustomArrayAdapter adapter; adapter = new CustomArrayAdapter(this,R.layout.row_item,items); ثالثًا نربط قائمة العرض بالشيفرة ونستدعي التابع ()setAdapter: private ListView customLV; customLV = (ListView) findViewById(R.id.listview); customLV.setAdapter(adapter); بهذا نكون قد انتهينا من تكوين قائمة العرض المطلوبة، يتبقى أن نجعل عناصر قائمة العرض تستجيب عند الضغط عليها وتقوم بفتح نشاط جديد، لذا أولًا نقوم بعمل نشاط جديد بالضغط بالزر اليمن على اسم الحزمة واختيار: New > Activity > Empty Activity ونسميها DescriptionActivity. ولفتح هذا النشاط عند الضغط على عناصر قائمة العرض نقوم باستدعاء التابع ()setOnItemClickListener وبداخله نفتح النشاط الجديد ونرسل إليه اسم العنصر الذي قام بفتحه حتى يعرضه. package apps.noby.customlistviewexample; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import java.util.ArrayList; public class MainActivity extends Activity { private ListView customLV; private CustomArrayAdapter adapter; private ArrayList<ListItem> items; String [] colorsArray = {"Red","Yellow","Blue","Black","Green","Brown","Grey"}; int [] colorsImage = {R.drawable.red,R.drawable.yellow,R.drawable.blue,R.drawable.black,R.drawable.green,R.drawable.brown,R.drawable.grey}; public static final String COLOR_KEY = "colorName"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); items = new ArrayList<ListItem>(); for(int i=0;i<colorsArray.length;i++){ ListItem item= new ListItem(); item.imgSrc=colorsImage; item.title = colorsArray; item.desc = colorsArray + " Color!"; items.add(item); } customLV = (ListView) findViewById(R.id.listview); adapter = new CustomArrayAdapter(this,R.layout.row_item,items); customLV.setAdapter(adapter); customLV.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(MainActivity.this,DescriptionActivity.class); intent.putExtra(COLOR_KEY,colorsArray[position]); startActivity(intent); } }); } } أخيرًا نقوم بتهيئة واجهة المستخدم الخاصة بالنشاط الجديد لتعرض النص المرسل إليها. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/txt" android:textSize="20sp"/> </LinearLayout> ولعرض النص داخل الـ TextView نقوم في الشيفرة باستدعاء الـ Intent الذي قام بفتح النشاط واستخراج منه البيانات المرسلة وكتابتها على TextView كما يلي: package apps.noby.customlistviewexample; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class DescriptionActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_description); String str = getIntent().getStringExtra(MainActivity.COLOR_KEY); TextView tv = (TextView) findViewById(R.id.txt); tv.setText("Welcome to " + str + " Color Home!!"); } } والآن نقوم بتجربة التطبيق على المحاكي حتى نتأكد من عمله بالشكل المطلوب. البحث داخل عناصر قائمة العرض التي تم تخصيصها تطبيق 6 في هذا التطبيق سنكرر ما قمنا به سابقًا من بحث عن نص معين داخل قائمة العرض ولكن الاختلاف هنا سيكون أن قائمة العرض ليست بهذه البساطة وتتكون من عنصر واحد فقط وهو النص، ولكنها تتكون من صور وعدة نصوص مختلفة لذا ينبغي علينا أن نصنع بأنفسنا طريقتنا الخاصة للبحث وتنقية العناصر من القائمة وترك العناصر التي يتم البحث عنها. أولًا نقوم بتغيير ملف الواجهة activity_main.xml وإضافة عنصر EditText. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableLeft="@drawable/ic_search_black_24dp" android:hint="Search..." android:id="@+id/searchedittext"/> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listview"/> </LinearLayout> ثانيًا نربط عنصر EditText في الشيفرة الأساسية ونستدعي التابع ()addTextChangedListener وبداخل الدالة ()onTextChanged نستدعي التابع الخاص بالتنقية كما سبق. package apps.noby.customlistviewexample; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ListView; import java.util.ArrayList; public class MainActivity extends Activity { private ListView customLV; private CustomArrayAdapter adapter; private ArrayList<ListItem> items; String[] colorsArray = {"Red", "Yellow", "Blue", "Black", "Green", "Brown", "Grey"}; int[] colorsImage = {R.drawable.red, R.drawable.yellow, R.drawable.blue, R.drawable.black, R.drawable.green, R.drawable.brown, R.drawable.grey}; public static final String COLOR_KEY = "colorName"; EditText searchET; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); items = new ArrayList<ListItem>(); for (int i = 0; i < colorsArray.length; i++) { ListItem item = new ListItem(); item.imgSrc = colorsImage; item.title = colorsArray; item.desc = colorsArray + " Color!"; items.add(item); } searchET = (EditText) findViewById(R.id.searchedittext); customLV = (ListView) findViewById(R.id.listview); adapter = new CustomArrayAdapter(this, R.layout.row_item, items); customLV.setAdapter(adapter); customLV.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(MainActivity.this, DescriptionActivity.class); intent.putExtra(COLOR_KEY, colorsArray[position]); startActivity(intent); } }); searchET.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } @Override public void afterTextChanged(Editable s) { } }); } } أخيرًا يتبقى أن نقوم بكتابة تابع التنقية الخاص بنا، وسنقوم بكتابته داخل الصنف CustomArrayAdapter. داخل CustomArrayAdapter نقوم بإنشاء كائن آخر من ArrayList ونجعله يساوي البيانات التي سنضعها في قائمة العرض، مثله كالكائن data. private ArrayList<ListItem> dataTemp; public CustomArrayAdapter(Context context, int resource, ArrayList<ListItem> objects) { super(context, resource,objects); con = context; data = objects; resLayout = resource; dataTemp = objects; } بعد ذلك نعيد كتابة التابع الخاص بالتنقية والمتواجد أيضًا داخل الأب Arrayadapter لذا سنقوم بعمل Override لهذا التابع. والتابع هو ()getFilter ويعيد كائن من الصنف Filter وبداخل هذا الصنف تظهر لدينا دالتين جديدتين كما يلي: @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { } @Override protected void publishResults(CharSequence constraint, FilterResults results) { } }; } الأولى ()performFiltering هي المسؤولة عن عملية التنقية ونكتب بداخلها كيف تتم تنقية العناصر وما هي العناصر التي ستظهر عند كتابة نص معين ويتم تخزين النص الذي تم كتابته وعلى أساسه تتم عملية التنقية داخل المتغير constraint. الثانية ()publishResults هي المسؤولة عن تغيير محتوي البيانات التي تعرضها قائمة العرض حيث تأتي النتائج بعد التنقية داخل الكائن results. سنبدأ أولًا بكتابة طريقة التنقية التي سنتبعها وهي، نتأكد أن النص الذي ستتم التنقية على أساسه وممثل في المتغير constraint ليس فارغًا وذلك عن طريق الجملة المنطقية التالية: constraint == null || constraint.length() == 0 وتعني هل المتغير constraint لم يُخزن بداخله أي بيانات أو تم تخزين نص فارغ، لذا سنضع هذه الجملة داخل الجملة الشرطية if وإن تحققت فذلك يعني أنه لا داعي للتنقية وستظل عناصر القائمة كما هي، أما إذا كان خلاف ذلك ويوجد نص فسنقوم بعملية التنقية. FilterResults results = new FilterResults(); if(constraint == null || constraint.length() == 0){ results.values = dataTemp; results.count = dataTemp.size(); } else{ } return results; لاحظ أن الكائن results هو المتغير الذي سنخزن بداخله ناتج التنقية، ويتكون من عنصرين مهمين الأول results.values وهنا يتم تخزين البيانات الجديدة و results.count ويتم تخزين عددهم. طريقة التنقية ستكون كالتالي: نصنع حاوية جديدة لتخزين العناصر الناتجة من التنقية. لكل عنصر من العناصر القديمة في قائمة العرض نقوم بمقارنته بالنص المكتوب لنرى هل يحتوي على حروفه. إن كان يحتوي على أحد حروفه ننقله إلى حاوية التخزين الجديدة التي صنعناها. بعد الانتهاء من كافة العناصر نعيد النتيجة ليتم تحديث قائمة العرض بالعناصر الجديدة. ArrayList<ListItem> filterList = new ArrayList<ListItem>(); for (int i = 0; i < dataTemp.size(); i++) { ListItem item = dataTemp.get(i); if ( (item.title.toLowerCase()).contains(constraint.toString().toLowerCase())) { ListItem filterItem = new ListItem(); filterItem.imgSrc = dataTemp.get(i).imgSrc; filterItem.title = dataTemp.get(i).title; filterItem.desc = dataTemp.get(i).desc; filterList.add(filterItem); } } results.values = filterList; results.count = filterList.size(); لاحظ أننا نقوم بالتنقية على أساس النص المخزن داخل title، وأننا نقوم بتحويل هذا النص إلى حروف صغيرة ومقارنته بالنص الذي نبحث عنه أيضًا بعد تحويله لحروف صغيرة لتوحيد طريقة كتابة الكلمة. ونستخدم التابع ()contains والذي يتأكد هل الكائن الذي قام باستدعاء هذا التابع يحتوي على النص الذي نمرره للتابع أم لا، إن كان يحتويه فسيعيد القيمة المنطقية true أما إذا كان لا يحتويه فسيعيد false. بعد ذلك ننتقل إلى الدالة الأخرى لنشر النتائج الجديدة في قائمة العرض، ونقوم بنقل البيانات المخزنة في results.values إلى المتغير data حتى يتم تحديث قائمة العرض باستدعاء التابع ()getView بعد استدعاء ()notifyDataChanged. data = (ArrayList<ListItem>) results.values; notifyDataSetChanged(); لتصبح الشيفرة النهائية للصنف CustomArrayAdapter بعد التعديل: package apps.noby.customlistviewexample; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Filter; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; public class CustomArrayAdapter extends ArrayAdapter{ private Context con; private ArrayList<ListItem> data; private ArrayList<ListItem> dataTemp; private LayoutInflater inflater; private int resLayout; public CustomArrayAdapter(Context context, int resource, ArrayList<ListItem> objects) { super(context, resource,objects); con = context; data = objects; resLayout = resource; dataTemp = objects; } @Override public int getCount() { return data.size(); } @Override public View getView(int position, View convertView, ViewGroup parent) { inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rootView = inflater.inflate(resLayout,null); ImageView img = (ImageView) rootView.findViewById(R.id.imgview); TextView title = (TextView) rootView.findViewById(R.id.titleview); TextView desc = (TextView) rootView.findViewById(R.id.descview); ListItem item = data.get(position); img.setImageResource(item.imgSrc); title.setText(item.title); desc.setText(item.desc); return rootView; } @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); if (constraint == null || constraint.length() == 0) { results.values = dataTemp; results.count = dataTemp.size(); } else{ ArrayList<ListItem> filterList = new ArrayList<ListItem>(); for (int i = 0; i < dataTemp.size(); i++) { ListItem item = dataTemp.get(i); if ( (item.title.toLowerCase()).contains(constraint.toString().toLowerCase())) { ListItem filterItem = new ListItem(); filterItem.imgSrc = dataTemp.get(i).imgSrc; filterItem.title = dataTemp.get(i).title; filterItem.desc = dataTemp.get(i).desc; filterList.add(filterItem); } } results.values = filterList; results.count = filterList.size(); } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { data = (ArrayList<ListItem>) results.values; notifyDataSetChanged(); } }; } } الآن قم بتجربة التطبيق على المحاكي للتأكد انه يعمل كما ينبغي. بهذا نكون قد وصلنا إلى نهاية هذا الدرس، في انتظار تجربتكم وآرائكم.1 نقطة
-
ينظر إلى الساعة ... "ممتاز! إنّها السابعة صباحا. أمامي ساعة كاملة قبل استيقاظ عائلتي، سأنجز الكثير من العمل، كم أحبّ أيّام السبت!". عمل ... عمل ... عمل ... عمل ... عمل ... "وأخيرا أنهيت العمل، لقد كانت جلسة عمل مكثّفة". ثمّ ينظر إلى التقويم ... "ماذا؟ اليوم هو الأحد؟ أين ذهب يوم السبت؟" يحيل نظره إلى زوجته ... "ماذا تعنين بأنّك أخذت البنات إلى السينما بدوني؟ وأكلتم البوظة أيضا؟ لماذا لم تطلبي مني الذهاب معكم؟ آآه، لقد طلبت مني ذلك. أنا الذي كنت مشغولا جدّا بالعمل...". هل تبدو لكم هذه الحالة مألوفة؟ يخوض المستقلون في الكثير من الأحيان في عادة العمل المتواصل بدون انقطاع، ومن الممكن لهذه العادة أن تجعل العميل معجبا بك ولكنّ عائلتك ستكون مستاءة منك وسيكون جسمك منهكا جدّا وسيصبح عقلك خاملا. لذلك فالطّريقة الفعّالة التي من شأنها أن تحافظ على نجاح علاقاتك مع عالمك الحقيقيّ ونجاح عملك في آن واحد هي أن تأخذ قسطا من الراحة بين الحين والآخر، ومن الأحسن أن يكون ذلك بشكل يومي. ولكن كيف لك ألاّ تعمل وهناك عمل متواصل ينتظرك؟ كُن صارما واتّبع برنامجا يوميّا من أجل مصلحتك. إدراج أوقات الراحة في البرنامج اليومي سيكون لديك على الأرجح جدولا يوميّا للعمل يحتوي على مخطّطات لمشاريعك تلتزم بها دائما وتتّبع قائمة مهامك المدرجة فيه بشكل جيّد. فمثلا أنت تعلم أنّه من العاشرة صباحا إلى الثالثة مساءً هو وقت مخصّص لتنفيذ طلبات العملاء ومن الرابعة مساءً إلى السادسة مساءً وقت مخصّص للقيام بشتّى الاتصالات عبر الإنترنت ومن السابعة مساءً إلى العاشرة ليلا وقت محدّد للمزيد من المهام الخاصّة بالعملاء. أن يكون لديك برنامج واضح ومنظّم، فهذا شيء ممتاز وأنا أوصي به لحد كبير. ومع ذلك، لن تكون الاستفادة كاملة وتامّة إن لم تُدرج أوقات راحتك في برنامجك اليوميّ. إنّ من أسوأ الأشياء التي يمكنك فعلها فيما يتعلق بأوقات راحتك هو عدم جدولة هذه الأوقات ضمن جدول الأعمال اليومي ، حيث أنّه لا يكفي أن تترك فراغا بين مشاريعك وتقول "هذا هو وقت فراغي !" وإنّما يجب عليك تدوين وإدراج هذا الوقت المخصّص لراحتك في برنامجك. وعليه فإنّ جدولة أوقات الراحة الخاصّة بك ضمن برنامجك دليل على أنّها تحظى بنفس الأهميّة التي تحظى بها باقي المشاريع الأخرى، وأيضا فهي تذكّرك أنّه عليك أن تأخذ قسطا من الراحة لأنّه من السهل أن تنسى استراحتك عندما لا تكون مدوّنة في البرنامج. إنّ اشتمال برنامجك اليوميّ على أوقات راحتك سيعطيك دائما شيئا لتتطلّع إليه، فمن الممكن أن تصبح أكثر إنتاجيّة بمجرّد أن تعلم أنّ هناك وقت راحة ينتظرك بعد هذا العمل لأنّ إتمام مهمّة معيّنة يصبح أسهل بكثير عندما تعلم أنّك ستكافأ باستراحة في آخر المطاف. التزم ببرنامجك إذا قمت ببرمجة وقت للراحة وخصوصا إذا قمت بجدولته في جدول أعمالك، عليك أن تلتزم به، لا تختلق أعذارا أو تعد نفسك أن تأخذ غدا قسطا أطول من الراحة تعويضا عن الذي ضاع منك اليوم. وفي الحقيقة هذا هو الجزء الأصعب لكثير من المستقلين لأنّنا نقوم بتحديد ساعات عملنا بأنفسنا فلو نرغب بالعمل 16 ساعة نستطيع فعل ذلك، ولكن أخذ وقت من الراحة بعيدا عن العمل مهمّ جدّا للحفاظ على صحة عقلك واتّزانك وعلاقاتك مع العالم الحقيقيّ من حولك (تذكّر أولئك النّاس الذين تدعوهم بالأصدقاء والعائلة، أنا متأكّد من أنّهم يودّون رؤيتك معهم من حين لآخر). إن واجهتك صعوبة في اتباع برنامج العمل الذي أنجزته، اضبط المنبّه الموجود في هاتفك ليساعدك في ذلك. كما يمكنك أيضا أن تطلب من صديقك أن يهاتفك عندما يحين وقت راحتك ليذكّرك بأن تنهض من أمام الحاسوب ! قُم بعمل أيّ شيء يساعدك في الابتعاد عن شاشة الحاسوب الذي سيبقى دائما في المكان الذي تتركه فيه في كلّ مرّة على غرار العالم المحيط بك المتغيّر باستمرار والخبرات التي من الممكن أن تكتسبها. اتبع سياسة فرق تسد بدلا من إدراج كل مهامك في قائمة متسلسلة، جرّب تقسيم هذه القائمة إلى مجموعة من الأجزاء، فمثلا قُم بجدولة الجزء الأول في الصباح قبل موعد أخذ الاستراحة والجزء الثاني بعد الزّوال والجزء الثالث في آخر النّهار ولا تنس أن تُدرج بين كلّ هذه الأجزاء أوقات راحتك، فالهدف المراد تحقيقه من تجزئة قائمة مهامك هو التّأكد من إنجاز مجموعة المهام المُدرجة في كل جزء قبل حلول موعد الاستراحة الخاصة بك. ومن إيجابيات تقسيم قائمة المهام هي سهولة أخذ قسط من الراحة عند الانتهاء من الأعمال والمهام الخاصة بك كمستقل لأنّ التوقف عن العمل يصبح أمرا طبيعيّا وتلقائيّا لديك كما أنّك تكون ميّالا أكثر للاسترخاء، وقيامك بهذا التقسيم يجعل أوقات استراحاتك ممتعة وخالية من التوتر لأنّك في الواقع لست قلقا بشأن المهام غير المنجزة في رزنامتك فعند انتهاء فترة الراحة ستعود إلى إنجاز قائمة جديدة من الأعمال بنفس جديد. خطط ماذا تفعل في وقت راحتك (اجعله ممتعا ومسليا) لكن إلى أي مدى يُعتبر ذلك مُريحًا ومُسلّيّا؟ السّرّ وراء جعل فترة الاستراحة وقتا مرحا ومسلّيا هو أن تخطّط له من قبل. نعم، قُم بكتابة مختلف الأنشطة التي تستطيع القيام بها خلال هذه الفترة، فمن بين الأنشطة التي تستطيع عملها مثلا هو أن تشاهد حلقتين من مسلسلك المفضّل ثمّ بعد ذلك تستطيع القيام بحرب تاريخيّة مع أطفال الجيران باستخدام بالونات الماء ! عليك أن تخطّط جيّدا في كيفية اغتنام كلّ دقيقة تقضيها بعيدا عن العمل، إن لم تفعل هذا فمن المحتمل أن تعود للعمل قبل انقضاء فترة الراحة أو أن تنتهي باستراحة تقتصر نشاطاتها على غسل الملابس وكيّها وتنظيف المنزل ! لهذا يمكنك أن تضع لائحة مخصّصة بالنشاطات المسلّية فوق مكتب العمل والتي تجد في القيام بها استمتاعا وترفيها عن النّفس ولا تأخذ منك وقتا طويلا في التّخطيط، بهذه الطّريقة إذا نسيت أن تضع مخطّطا لوقت استراحة اليوم، يمكنك أن تختار أيّ نشاط ترفيهيّ من اللائحة أمامك لتوفّر وقتك وتستمتع بوقت راحتك أكثر. خطط للمشاريع التي تأتي بعد وقت الراحة لقد انتهت للتّو فترة راحة رائعة ومسليّة وها أنت ذا تُهيّئ نفسك لتغرق مرة أخرى في بحر العمل ولكنّك لست متأكّدا من ماهية المهام التي ستقوم بإنجازها، لذلك ستُضطر لقضاء الساعة القادمة في التفكير في المشاريع التي يمكن عملها الآن. وأسوأ من هذا السيناريو هو التخطيط للأعمال التي ستقوم بها بعد وقت الراحة في وقت الاستراحة نفسه، انتبه ! لا تفعل ذلك ! إذن خطّط لمشاريعك التي تريد إنجازها بعد وقت راحتك قبل أن يصل الموعد المخصّص لها (لوقت الراحة) واحرص دائما على عمل مخطّط واضح عند رجوعك لإتمام مهامك لأنّه سيساعدك على تجنّب تضييع الوقت الذي كنت حدّدته لوقت راحتك وأيضا الوقت الثمين المخصّص لعملك. قم باتخاذ الإجراءات اللازمة إن كنت تخطّط للابتعاد عن العمل بضعة أيّام أو ربّما أطول، تأكّد من إعلام عملائك بهذا الأمر مسبقا فهذا يدلّ على أخلاقك الكريمة واحترافيّتك في العمل، وسيتفهم معظم العملاء احتياجك لأخذ بعض الوقت خارج إطار العمل خاصّة إن كان الأمر يتعلق بتمضية الوقت مع العائلة. قبل أن تبدأ عطلتك المبرمجة، ناقش مع عملائك خطّة العمل التي تلائم كليكما قبل وأثناء العطلة التي تريد أخذها، مثلا هل تريد القيام بالمزيد من المشاريع قبل العطلة؟ هل سيكون بإمكانك الرّد على الرسائل التي تصلك في البريد الإلكتروني والاتصالات الهاتفية أثناء العطلة؟ سيمنح التّشاور والمناقشة في كلّ هذه الأمور العملاء آمالا واقعيّة فيما يخصّ ما الذي يمكنك تقديمه لهم وأنت أثناء العطلة. اجعل أوقات راحتك غير قابلة للتفاوض يكون التّوقف عن العمل في غالب الأحيان الجزء الأصعب، لذلك لا تسمح لنفسك بالتّغاضي أو تجاهل وقت الراحة الخاصّ بك لأنّ هذا الأمر ضروريّ لصحتك الجسديّة والعاطفيّة والعقليّة. من دون استراحة، ستتدهور جودة عملك وسيلاحظ العميل ذلك، ولهذا عليك ألاّ تُقامر بسعادة عملائك (وراتبك) من خلال العمل المتواصل غير المنقطع. يُعتبر أخذ أقساط من الراحة بشكل منتظم طريقة جيّدة تساعدك على تجنب الإرهاق المُفرط. ربّما بدأت العمل كعامل مستقل لأنّه أمر تستمتع بالقيام به، ولكن إن كنت تعمل كثيرا للدرجة التي تشعر فيها بالنّفور من عملك، فمن الأحسن أن تبحث عن عمل في شركة ! لهذا يجب عليك أن تحافظ على طاقتك لأجل عملك الحرّ وذلك بعدم قبول أن تصبح عبدا لعملك طوال الوقت، يمكنك أن تأخذ نزهة ما بين الحين والآخر، أن تقرأ قصائد أو كُتبًا، أن تلعب مع أولادك... ذكّر نفسك دائما أنّ الحياة أهمّ بكثير من العمل. ابدأ من اليوم وخصّص بعض الوقت لوضع أوقات للراحة في برنامجك اليوميّ وقُم بكتابة بعض الأنشطة التي يمكنك فعلها خلال استراحتك، ومن بين اقتراحاتي التي أفضّلها هي القراءة والقيام ببعض التمارين الرياضيّة وقضاء بعض الوقت مع العائلة. هل لديك وقت منتظم مخصّص للراحة؟ ماهي الأنشطة التي تستمتع بها خلال هذا الوقت؟ ترجمة -وبتصرّف- للمقال How to Take a Break Even When Your Work Doesn’t لصاحبته Ardelia Lee.1 نقطة
-
أصدقائي:@alilodzو @أسامة عرب، الحمدلله تم حل المشكلة بالدخول للسيف مود وحذف الدرايفر ثم تنزيله تثبيته من خلال موقع لينوفو (موقع الشركة المُصنِّعة للجهاز)، وذلك بعد تكرار الأمر حوالي 5 أو 6 مرات. شكراً لكم كثيراً لإهتمامكم، وأعتذر إن تسببت بأي إحراج/إزعاج. تحياتي.1 نقطة
-
أريد مكتبة لمعالجة الصور على نظام أندرويد، فهل توجد مثل هذه المكتبة؟ أريد مكتبة مشابه لـ OpenCV للسي بلس بلس.1 نقطة
-
إذا أردت يمكنك استخدام OpenCV فهي تدعم أنظمة أندرويد بشكل رسمي كما يمكنك استخدامها مع أجهزة الآيفون بدون مشاكل. أما إذا أردت بديل لهذه المكتبة للغة جافا فيمكنك استخدام مكتبة JavaCV، والتي أعتقد أنها أفضل من المكتبة الأولى بالنسبة لأندرويد بما أنها توفر JAVA API. عيبها الوحيد أن توثيقها ليس كافيا.1 نقطة
-
أخشى أنك قد تضطر لإعادة التثبيت من جديد، لأن الدخول إلى السيف مود وتعطيل التعريف القديم ثم تثبيت الجديد هو الحل الوحيد الذي وجدته في الإنترنت. واحرص في المرات القادمة على تثبيت التعاريف من المواقع الأصلية فقط. تحياتي لك1 نقطة
-
شكرا جزيلا لك على ردك الكريم1 نقطة
-
1 نقطة
-
حسب ما يبدو لي هي أن أحد المكتبات ناقصة وهي مكتبة requests والتي تختلف عن مكتبة request المدمجة بشكل افتراضي في بايثون. إذا كنت تستخدم نظام لينكس فيمكنك تثبيت هذه المكتبة عن طريق السطر التالي: sudo pip install requests أما في نظام ويندوز فيجب استخدام هذه الطريقة: > C:\Python32\Scripts\easy_install.exe requests1 نقطة
-
1 نقطة
-
أخي أفضل معالج لحد الآن هو Intel Core I7-6700K Intel Core i7-5820K لكن يجب أن تحدد مبتغاك من اقتنائك لمعالج فمثلا إذا كنت تريده لمجال الألعاب يكفيك Intel Core i3 فقط أما إذا كنت مبرمج أو مصمم Intel Core i5,i3 يحقق مرادك يوجد العديد من المعالجات لكن يجب أن تحدد مرادك من اقتناء معالج عالي الكفاءات1 نقطة
-
السلام عليكم أخي قصدك أنك تعدل من خاصية inspect element ثم تعدل من consol وهذا أكبر خطأ يقع فيه المطور لكي تسهل الأمور على نفسك يلزمك إضافة رائعة خاصة بالـ web devloping وهي موجودة للمتصفحين mozilla ,chrome http://chrispederick.com/work/web-developer/ لكن اذا كنت تريد أن تقوم بتعريب القوالب اولا عليك الدخول الى موقع : http://www.rtl-er.com/ ثم عليك الدخول الى ملف القالب الذي تريد تحويله ليدعم العربية، ثم افتح ملف style.css وانسخ محتواه بالكامل والصقه في الخانة الموضحة في الصورة المرفقة أتمنى من صميم القلب أن تكون استفدت إن أصبت فمن الله تعالى وإن أخطأت فمن ومن الشيطان الرجيم1 نقطة
-
يجب أن تحدد هدفك من تعلم لغات البرمجة ،لأن لغات البرمجة تختلف في الاغراض التي انشتئت من اجلها وكل لغة لها ميدان معين تكون اقوى فية من البقية وانسب واسهل بالطبع هناك لغات عامة يستطيع المحترف فيها ان يؤدي اي مهمة معينة او مخصصه ولكن ايضا كل لغة لها خصوصيتها في مجالها وتوفر على المبرمج الكثير من الجهد في مجال عملها او الميدان الذي اشتهرت فية . مثلا اذا كنت تريد تعلم البرمجة لكي تنشى مواقع وتطبيقات انترنت يجب عليك ان تتعلم لغة ال html .والسي اس اس Css اولا وربما الجافاسكربت فيما بعد لتضيف التفاعلية الى اكوادك ومواقعك وربما لاحقا لغة متقدمة للبرمجة علي الويب يجب عليك تعملها قد تكون البي اتش بي او الاي اس بي اما اذا كنت تريد دخول عالم البرمجة من اجل انشاء تطبيقات تعمل على الهواتف الذكية ومنصات الاندرويد واجهزه الايفون فيجب عليك تعلم لغة اوبجكتف سي Objective-C لبرمجة تطبيقات اجهزه ابل والجافا لتطبيقات الاندرويد اذا كنت تريد تعلم البرمجة لانشاء تطبيقات سطح المكتب والانظمة الادارية وانشاء انظمة معلومات يجب عليك ان تتعلم لغة متقدمة مخصصة للتعامل مع قواعد البيانات كالسي شارب او الجافا او الدلفي وبجانبها يجب ان تتقن تقنية قواعد البيانات ولغة الاسكيو ال للتعامل مع قواعد البيانات وتطبيق ادارة قواعد البيانات كميكروسوفت اسكيوال سرفر او الاكسس كبداية وكيف تتعامل معه من داخل الكود وتتصل بقواعد البيانات وتقوم بعمليات البحث والاسترجاع والحذف والاظافة والتعديل اما اذا كان غرضك ان تقتحم عالم البرمجة بشكل عام وتكون مطور محترف فالبداية قد تكون من لغات اصيلة تعلمك مفاهيم واسس البرمجة بشكل عام ومنها تتعلم كيفيه عمل البرنامج وما طرق خزن البيانات فية والتعامل مع الذاكرة وادارتها واكثر لغة مناسبة لهذا الشي هي ام اللغات كما اسميها وهي السي فلغة السي : تعلمك كيف تكتب كود منظم وفعال لغة الجافا : اكثر لغات البرمجة عملية وانتاجا لغة البايثون : جديدة سهلة التعلم وممتعة لغة الجافاسكربت : لانشا تطبيقات تفاعلية علي الويب في الأخير أعرف أني طولت في الموضوع لكن المهم الفائدة بالنهاية سوا كان غرضك من تعلم البرمجة هو للهواية او للوظيفه او للاحتراف فانه من المفيد ان افصل لك لغات البرمجة من حيث مجالات استخدمها واجمعها في قوالب مشتركة حسب الميادين التي تخدم فيها وتناسبها اكثر لبرمجة تطبيقات الويب والتعامل مع قواعد البيانات او ما يسمي الباك ايند هناك لغات خاصه بهذا المجال وهي البايثون , الروبي , الدوت نت , البي اتش بي php , asp.net , Python , Ruby لبرمجة واجهات تطبيقات الويب وانشا الصفحات وتنسيقها وغيرة من المهام المتعلقة بتصميم الواجهات الخاصه بالمواقع هنا لديك ال اتش تي ام ال والسي اس اس وكذلك الجافا سكربت html , css , javascript لبرمجة تطبيقات الموبايل والهواتف الذكية لديك ال اوبجت سي والجافا Objective-C Java (for Android) لبرمجة الالعاب وتطبيقات الفيديو والانميشن لديك السي والسي بلس والجافا C/C++, OpenGL, java برمجة تطبيقات قواعد البيانات ونظم المعلومات لديك في هذا المجال لغات مثل السي شارب والفيجول بيزك دوت نت الدلفي والجافا ايضا . VB , C# , Java الآن نأتي أيهما الأفضل اذا استطعت فهم الـ #C سيسهل عليك فهم الـ java والعكس ايضآ صحيح .. اذا انا انصحك ب #C1 نقطة
-
تحتاج لأن تعمل على مشاريع برمجية صغيرة، ولو بالمجان ستستفيد من ذلك خبرة عملية جيدة إن شاء الله.1 نقطة
-
وصلتني الرسالة التالية من أحد قراء زاجل. أعيد هنا نشر جوابي عليها، علما أن هذا الجواب/الموضوع ليس استشارة قانونية دقيقة التفاصيل، بل مجرد موضوع توجيهي يقدم تعريفا لموضوع معين بشكل غاية في التبسيط، دون الدخول في كل تفاصيله المعقدة. الرسالة:بالأمس كنت أقرأ كتاب Anyone Can Do It يحكي قصة مؤسسي سلسلة مقاهي (جمهورية القهوة: coffee republic). حيث أنهم احتاجوا لفتح أول متجر لهم إلى قرض من البنك ولم يقوموا بإدخال مستثمر معهم من البداية، ولكن بعد أن نجح أول متجر لهم أرادوا التوسع لإنشاء 6 متاجر في سنة واحدة ولم يستطيعوا فعل ذلك بأخذ قرض مرة أخرى ولكن في هذه المرة أدخلوا مستثمرا معهم. يحكي الكتاب أن المستثمر أخذ حصة 40% من الشركة بينما المؤسسين اكتفوا ب 60%. سؤالي هنا هو كيف قاموا بتحديد قيمة شركتهم مع أنهم لا يملكون سوى متجر واحد وتقسيم النسبة 60% للمؤسسين و40% للمستثمر؟ بعد ذلك قاموا بافتتاح الستة متاجر التي كانوا يريدون فتحها في سنة وأرادوا التوسع مرة أخرى وافتتاح 25 متجر أخر على مدار عامين واحتاجوا لإستثمار بقيمة 4.5 مليون جنية إسترليني. لم يذكر كم كانت حصة المسثمر الجديد ولكن ذكر أن حصة المؤسسين أصبحت 27% من قيمة الشركة! سؤالي في هذه النقطة: المستثمر الجديد من أين قام بأخذ حصته هل كانت من ال 60% الباقية للمؤسسين بعد الاستثمار الأول؟ أم من قيمة الشركة ككل؟ أم ماذا؟ في النهاية أصبحت شركة coffee republic شركة كبيرة ولها مكاتب رسمية ومدير عمليات وموظفين كثيرون وقد قال المؤسسون الأخوان (سحر وبوبي) أن الأجواء أصبحت مختلفة تماما عما كانت عليه سابقا عندما كانوا شركة صغيرة واختفت الروح التي كانت تسود الفريق في البداية مما أدي لرحيل كل الفريق الذي كان يعمل مع المؤسسين منذ البداية وبعد ذلك غادر المؤسسين أيضا. حقيقة لقد انصدمت عندما عرفت أن المؤسسن أيضا قد رحلوا عن الشركة! لماذا حدث ذلك؟ لماذا يترك المؤسسين الشركة بعد كل هذا التعب؟ وعندما رحل المؤسسون هل يعنى هذا رحيلهم بشكل نهائي أي انهم باعوا أسهمهم وكل شيء أم أنهم تخلوا فقط عن المهام الإدارية و لكن ما زال لهم أسهم في الشركة؟ الجواب:لم أقرأ ذلك الكتاب، لذلك لا يمكنني أن أفيدك بدقة حول كيف تم تقييم الشركة. لكن بصفة عامة لا يوجد جواب قاطع حول تقييم الشركات، فالمسألة خاضعة لقدرة صاحب المشروع على التفاوض وكيف سيقنع المستثمرين بقيمة مشروعه. ومن بين المعايير التي يتم الاعتماد عليها في تحديد قيمة المشروع، الإيرادات الحالية، نسبة النمو والأرباح المتوقعة خلال فترة مستقبلية معينة. (سبق أن أجبت عن سؤال شبيه بهذا) بالنسبة لسؤالك الثاني، المستثمر لا يأخذ حصته من أي أحد، بل تضاف لأجله أسهم إضافية لمجموع أسهم الشركة. لكن حين تضاف الأسهم الجديدة فإن حصة الآخرين (أي نسبة أسهمهم إلى مجموع الأسهم) تنقص، في حين أن القيمة يمكن أن ترتفع. مثلا: لدى الشركة 100 سهم وقيمتها 100 دولار. المؤسس يملك 60% (أي 60 سهما، وقيمتها 60 دولارا)، والمستثمر الأول يملك 40% (أي 40 سهما، وقيمتها 40 دولارا). تم الاتفاق مع مستثمر جديد لضخ مبلغ إضافي قدره 50 دولار، وفق تقييم للشركة يبلغ 150 دولار. بعد ضخ المبلغ أصبحت قيمة الشركة الآن تساوي 200 دولار (التقييم الذي تم الإتفاق عليه + المبلغ الذي تم استثماره). الآن حصة المستثمر الجديد تبلغ 25%. في المرحلة التي تم فيها تقييم الشركة بـ 150 دولار، كان لدينا 100 سهم. أي أن كل سهم أصبح يساوي 1.5 دولار. بعد أن أضاف المستثمر الجديد مبلغ 50 دولار، فإنه سيحصل مقابل ذلك على عدد الأسهم التي توافق ذلك المبلغ أي حوالي 33 سهما. هذه الأسهم ستضاف إلى أسهم الشركة، ليصبح المجموع الآن حوالي 133 سهما. المستثمر الثاني يملك الآن 33 سهما، أي 25% من قيمة الشركة وهي تساوي 50 دولارا. أما المستثمر الأول فهو ما يزال يملك 40 سهما التي كان يملكها سابقا. لكن حصته الآن انخفضت إلى حوالي 30% (بسبب رفع أسهم الشركة) لكن في المقابل قيمة حصته ارتفعت (بفضل ارتفاع قيمة الشركة) من 40 دولارا إلى 60 دولارا. نفس الأمر بالنسبة للمؤسس، ما زال يملك 60 سهما، حصته من الشركة انخفضت إلى 45% وقيمة حصته ارتفعت إلى 90 دولارا. قد يبدو الأمر معقدا. حاول أن تعيد قراءة الأرقام بروية أكثر إلى أن تفهمها. بالنسبة لمغادرة المؤسسين، رواد الأعمال يبحثون دائما عن الابتكار وتحدي بناء منتجات وخدمات جديدة. لذلك كثيرا ما يغادر المؤسسون حين تكبر الشركات وتصبح إدارتها معقدة وتسيطر عليها البيروقراطية، خاصة لو أرادوا بدء شركة جديدة مختلفة. هذه ليست قاعدة عامة إنما الأمر متعلق بشخصية كل مؤسس والأهداف التي أرادها من تأسيس الشركة. خروج المؤسسين لا يعني بالضرورة بيعهم للأسهم. هو بالأساس خروج من الإدارة فقط، لكن يمكنهم بيع حصتهم لمستثمر آخر، لو كانت الشركة خاصة، أو بيع أسهمهم، على مراحل، في البورصة لو كانت الشركة عامة.1 نقطة