14/9/2013 - برمجة Android - بناء قائمة ListView بسيطة في واجهة المستخدم الرسومية




مرحباً بالجميع، سأبدأ اليوم أول درس من دروس البرمجة تحت نظام آندرويد و في هذا الدرس سأتحدث عن طريقة برمجة القوائم التي تظهر في واجهة المستخدم الرسومية و التي تُظهر له بعض البيانات ليتعامل معها.

مُقدمة
لعرض القوائم في واجهة المستخدم الرسومية في آندرويد فإننا نستخدم أداة (Widget أو View كما يُطلق عليها في عالم آندرويد) تُسمى ListView، وسنتعامل خلال هذا الدرس مع هذه الأداة لنرى كيف تعمل و ما الذي تُقدمه لنا من خدمات تُسهّل علينا من عملية إظهار القوائم في واجهة المستخدم الرسومية.

بناء قائمة بسيطة
سنبدأ أولاً بشيء بسيط ثم نتدرج في تطويره، كُل ما نريده الآن هو بناء قائمة بسيطة تحتوي على ثلاث عناصر بالمسميات التالية Item1, Item2, Item3 على الترتيب بشكل مشابه لما في الصوره التاليه :



في البداية سنضع الأداة ListView في الواجهة التي نُصممها بإستخدام مُصمم الواجهات الخاص بآندرويد والذي يأتي مع إضافة Ecplise، بفرض إننا نعمل على الواجهة الأساسية MainActivity فإننا سنتحتاج لتحرير الملف activity_main.xml الموجود في المجلد res/layout، ستجد الأداة ListView في القائمة Composite، كُل ما عليك وضعها في النافذه.

نذهب الآن لملفنا البرمجي (والذي أفترض في حالتنا إنّه MainActivity)، وكما إعتدنا بشكل دائم فإننا سنأخذ الكائن الذي يُمثّل القائمة التي أضفناها منذ قليل إلى واجهتنا الرسوميه لنتعامل معها برمجياً.

ListView listView = (ListView) findViewById( R.id.listView1 );

لاحظ البارامتر هنا، إسم قائمتنا في ملف activity_main.xml هو listView1 حيث أفترض إنك لم تقم بتغييره عند إضافة الأداة، في حال قمت بتغييره يجب أن تُغيّر البارامتر إلى الإسم المناسب، في حال لم تقم بتغيير شيء فلا تُزعج نفسك.

حسناً قائمتنا جاهزه الآن، ما رأيك بإضافة بعض البيانات إليها؟ :)

إضافة البيانات إلى القائمه (ListView) بإستخدام المُحوّل (Adapter)
بإستخدام المُحوّل (Adapter) يُمكننا إضافة البيانات في قائمتنا البسيطة هذه، وظيفة المُحوّل هي التعامل مع البيانات التي ستُضاف إلى القائمة الموجودة في واجهة المستخدم الرسومية، يُمكننا القول بإنّ المُحوّل هو البرج بين بياناتنا و بين قائمة (ListView)، مكتبات آندرويد البرمجية تُقدّم لنا بضع مُحولات، سأركز حالياً على نوع واحد وهو ArrayAdapter رَوماً للبساطه.

من إسمه ArrayAdapter يُمكننا الإستنتاج إنّه يتعامل مع المصفوفات، وهذا هو المطلوب بالنسبة لنا حالياً، كُل ما نريده هو إضافة مصفوفه من النصوص إلى قائمتنا في واجهة المُستخدم الرسومية، السطر التالي سيُنشؤ كائن من نوع ArrayAdapter :

ArrayAdapter listAdapter = new ArrayAdapter( this, android.R.layout.simple_list_item_1 );


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

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

كُل ما قمنا به الآن هو إنشاء كائن للمُحوّل الذي سيحتوي على بياناتنا التي نُريد عرضها، خطوتنا التاليه هي إضافة بعض البيانات لهذا المحوّل حتى يتسنى لقائمة ListView عرضها للمُستخدم.

الفئة ArrayAdapter تُقدّم لنا دالة إسمها add لإضافة البيانات سنستخدمها كالتالي :

		listAdapter.add( "Item 1" );
listAdapter.add( "Item 2" );
listAdapter.add( "Item 3" );


تبقّت لنا خطوه أخيره هامه و هي إخبار قائمتنا (ListView) التي عرفناها في البداية بأنّ المُحوّل الخاص بها و التي يجب عليها أخذ المعلومات منه هو listAdapter و الذي أضفنا إليه بياناتنا في الشيفرة السابقة، الفئة ListView تُقدّم لنا دالة بإسم setAdapter :

listView.setAdapter( listAdapter );


وكما هو واضح فإنّ البارامتر الذي مررناه هو كائن المُحوّل، هذا كُل شيء! حصلنا على قائمتنا البسيطه :).

الشيفرة الكاملة :

		ListView listView = (ListView) findViewById( R.id.listView1 );

// ... //

final ArrayAdapter listAdapter = new ArrayAdapter( this, android.R.layout.simple_list_item_1 );

listAdapter.add( "Item 1" );
listAdapter.add( "Item 2" );
listAdapter.add( "Item 3" );

// ... //

listView.setAdapter( listAdapter );

// ... //


تجدر الإشاره بإنّ هناك مُشيّد آخر للفئة ArrayAdapter يُمكنه أن يستقبل مصفوفة من نوع ArrayList موجودة مُسبقاً لوضعها في المُحوّل، مثال سريع :

		// ... //

ArrayList list = new ArrayList();

list.add( "Item 1" );
list.add( "Item 2" );
list.add( "Item 3" );

// ... //

final ArrayAdapter listAdapter = new ArrayAdapter( this, android.R.layout.simple_list_item_1, list );

// ... //

listView.setAdapter( listAdapter );

// ... //


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

معرفة العنصر الذي إختاره المُستخدم
ما قمنا به لحد الآن هو عرض قائمة بسيطة من المحتويات للمُستخدم، لنفرض أننا نُريد من المستخدم أن يضغط على عنصر معين من عناصر القائمة ليختاره، ثم نعرض له هذا العنصر عن طريق رسالة Toast.

ما سنقوم به هو معالجة الحدث OnItemClickListener، وكما هو واضح من إسمه فإنه سيتم تنفيذه عندما يضغط المستخدم على عنصر معين (الجدير بالذكر إنّ الفئة تُقدّم لنا كذلك طريقة لمعالجة الحدث OnLongClickListener والذي سيعمل عند الضغط مُطولاً على القائمة و هذا شائع الإستخدام في التطبيقات).

		listView.setOnItemClickListener( new OnItemClickListener()
{
@Override
public void onItemClick( AdapterView parent, View view, int position, long id )
{
Toast.makeText( getApplicationContext(), listAdapter.getItem( position ) , Toast.LENGTH_SHORT ).show();
}
});


الشيفرة السابقة بسيطة و ستقوم بالمطلوب، أولاً نُخبر قائمتنا (الموجودة على واجهة المُستخدم الرسومية) إننا نُريد معالجة الحدث OnItemClickListener و الدالة onItemClick تحتوي على الشيفرة التي يجب تنفيذها عندما يقوم المُستخدم بالضغط على عنصر معين في القائمة.

لاحظ إننا إستفدنا هنا من البارامتر position والذي يحتوي على المكان الذي يقع فيه العنصر في القائمة بدءاً من الرقم 0، ثم أرسلنا رسالة Toast للمستخدم و أستخدمنا داخلها الدالة getItem والتي يُقدمها لنا المُحوّل لأخذ قيمة نص العنصر الذي ضغط عليه المستخدم عن طريق معرفة مكان العنصر.

حسناً، هذا كُل شيء، أراكم في الجزء الثاني من هذا الدرس إن شاء الله :).