سنتناول في هذا الدرس من سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms تطبيقًا عمليًّا مفيدًا حول التعامل مع مخطّط الشبكة Grid Layout وهو عبارة عن تطبيق لوحة أرقام يمكن تطويرها لاحقًا لتصبح مثلًا تطبيق آلة حاسبة متعدّد الوظائف. اطلعنا في الدرس السابق على مخطّط الشبكة وتعلمنا بعض المبادئ الأساسيّة لاستخدامه. يمكنك مراجعة ذلك الدرس، أو من الممكن أن تبدأ مباشرةً في هذا الدرس.
فكرة التطبيق
سنعمل على كتابة تطبيق لوحة أرقام بسيط، حيث ستظهر أزرار تحمل الأرقام من 0 حتى 9 بالإضافة إلى زر الفاصلة العشرية، مع وجود زر لإلغاء آخر رقم تمّت كتابته. ستبدو واجهة التطبيق كما في الشكل التالي:
عندما ينقر المستخدم على أزرار الأرقام ستظهر هذه الأرقام تباعًا بجوار بعضها بالترتيب. أمّا عندما ينقر زر الإلغاء فسيتم إلغاء آخر رقم تمّ نقره. لنستعرض الشيفرة البرمجيّة لهذا التطبيق في الفقرة التالية.
الشيفرة البرمجيّة للتطبيق
ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه KeypadGrid، ثم أبق فقط على المشروعين KeypadGrid (Portable) و KeypadGrid.Droid كما وسبق أن فعلنا في هذا الدرس. بعد ذلك سنضيف صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في هذا الدرس سنسمّها KeypadGridPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="KeypadGrid.KeypadGridPage"> <Grid RowSpacing="2" ColumnSpacing="2" VerticalOptions="Center" HorizontalOptions="Center" WidthRequest="180" Grid.HeightRequest="300"> <Label x:Name="displayLabel" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="Large" LineBreakMode="HeadTruncation" VerticalOptions="Center" HorizontalTextAlignment="End" /> <Button x:Name="btnBackspace" Text="⇦" Grid.Row="0" Grid.Column="2" IsEnabled="False" Clicked="btnBackspace_Clicked" /> <Button Text="7" StyleId="7" Grid.Row="1" Grid.Column="0" Clicked="OnDigitButtonClicked" /> <Button Text="8" StyleId="8" Grid.Row="1" Grid.Column="1" Clicked="OnDigitButtonClicked" /> <Button Text="9" StyleId="9" Grid.Row="1" Grid.Column="2" Clicked="OnDigitButtonClicked" /> <Button Text="4" StyleId="4" Grid.Row="2" Grid.Column="0" Clicked="OnDigitButtonClicked" /> <Button Text="5" StyleId="5" Grid.Row="2" Grid.Column="1" Clicked="OnDigitButtonClicked" /> <Button Text="6" StyleId="6" Grid.Row="2" Grid.Column="2" Clicked="OnDigitButtonClicked" /> <Button Text="1" StyleId="1" Grid.Row="3" Grid.Column="0" Clicked="OnDigitButtonClicked" /> <Button Text="2" StyleId="2" Grid.Row="3" Grid.Column="1" Clicked="OnDigitButtonClicked" /> <Button Text="3" StyleId="3" Grid.Row="3" Grid.Column="2" Clicked="OnDigitButtonClicked" /> <Button Text="0" StyleId="0" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" Clicked="OnDigitButtonClicked" /> <Button Text="." StyleId="." Grid.Row="4" Grid.Column="2" Clicked="OnDigitButtonClicked" /> </Grid> </ContentPage>
من السهل فهم الرُماز السابق مع بعض الملاحظات البسيطة:
- في البداية لاحظ أنّنا قد أسندنا خصائص إضافيّة لمخطّط الشبكة مثل تباعد الأسطر RowSpacing وتباعد الأعمدة ColumnSpacing وذلك بهدف جعل الأزرار غير ملتصقة ببعضها البعض. كما أسندنا الخيارات الرأسية VerticalOptions والأفقية HorizontalOptions لكي تحمل كل منهما القيمة Center بهدف جعل الشبكة تظهر في مركز الشاشة.
- لم نستخدم في هذا التطبيق الخاصيّتين RowDefinitions و ColumnDefinitions اللّتان تحدثنا عنهما في الدرس السابق. إذ أنّه من الممكن اعتماد الإعدادات الافتراضيّة الخاصّة بهما، والبدء مباشرة بإضافة العناصر المرئيّة، حيث يمكن من خلال هذه العناصر تحديد السطر والعمود للخليّة التي نودّ وضع العنصر ضمنها كما سنرى بعد قليل.
- اللصيقة الوحيدة الموجودة في هذا التطبيق تُستَخدم لعرض الرقم الذي أدخله المستخدم. لاحظ أنّنا نريد عرضها في الخلية المحدّدة بالسطر الأوّل والعمود الأوّل، بالإضافة إلى الانتشار لعمودين متتاليين بسبب وجود الخصائص التالية: Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2". كما توجد خاصية أخرى ملفتة للنظر لهذه اللصيقة، وهي الخاصيّة LineBreakMode والتي تحمل القيمة HeadTruncation. هذه القيمة مفيدة في مثل هذه التطبيقات حيث يؤدّي وجودها إلى اقتطاع النص الذي تمّ إدخاله أولًا في حال لم تتسع اللصيقة لعرض كامل النص (يمكنك تجريب ذلك بنفسك فيما بعد).
- الزر الأوّل الذي يأتي بعد تعريف اللصيقة هو زر إلغاء آخر رقم مُدخل، واسمه btnBackspace، وهو مرتبط مع معالج حدث النقر btnBackspace_Clicked الموجود ضمن ملف الشيفرة البرمجيّة كما سنرى بعد قليل.
- بالنسبة لبقيّة الأزرار فأمرها بسيط. فكلّ زر نُعيّن له الخاصيّة StyleId للاحتفاظ بالقيمة النصيّة الموافقة للرقم الذي يحمله، فمثًلا الزر الذي يُعبّر عن الرقم 9 ستكون قيمة StyleId له تساوي "9"، وهكذا. الجدير بالملاحظة هنا أننا قد ربطنا جميع هذه الأزرار بنفس معالج الحدث وهو OnDigitButtonClicked، وهو أمر جائز تمامًا، بل ومن المفضّل القيام به. سنطّلع على هذا المعالج بعد قليل.
انتقل الآن إلى ملف الشيفرة البرمجيّة KeypadGridPage.xaml.cs الموافق لملف الرُماز السابق، واحرص على أن تكون محتوياته على الشكل التالي:
using System; using Xamarin.Forms; namespace KeypadGrid { public partial class KeypadGridPage : ContentPage { public KeypadGridPage() { InitializeComponent(); btnBackspace.IsEnabled = displayLabel.Text != null && displayLabel.Text.Length > 0; } void OnDigitButtonClicked(object sender, EventArgs args) { Button button = (Button)sender; displayLabel.Text += (string)button.StyleId; btnBackspace.IsEnabled = true; } void btnBackspace_Clicked(object sender, EventArgs args) { string text = displayLabel.Text; displayLabel.Text = text.Substring(0, text.Length - 1); btnBackspace.IsEnabled = displayLabel.Text.Length > 0; } } }
الشيفرة السابقة بسيطة للغاية، فالصنف KeypadGridPage يحتوي بشكل أساسي على معالجيّ لحدث النقر:
- المعالج الأوّل هو OnDigitButtonClicked وهو يُستدعى عندما ينقر المستخدم على أحد أزرار الأرقام بالإضافة إلى زر الفاصلة العشرية. وفي هذا المعالج يتم إضافة الرقم الذي نقره المستخدم توًّا إلى محتويات اللصيقة التي تعرض كامل الرقم المُدخَل. نبدأ أولًا بعمليّة تحويل cast للحصول على الزر الذي سبّب استدعاء هذا المعالج:
Button button = (Button)sender;
ثمّ استخلاص قيمة الخاصيّة StyleId له وضمّها إلى اللصيقة displayLabel:
displayLabel.Text += (string)button.StyleId;
ومن ثمّ تفعيل زر إلغاء آخر رقم بسبب أنّه قد أصبح هناك رقم واحد على الأقل بشكل مؤكّد ضمن اللصيقة.
- أمّا المعالج الثاني فهو btnBackspace_Clicked وهو يُستَدعى عندما يتم النقر على زر إلغاء آخر رقم مُدخَل. الشيفرة البرمجيّة ضمن هذا المعالج بسيطة، فهي تعمل أولًا على الحصول على النص الموجود أصلًا ضمن اللصيقة displayLabel وتضعه ضمن المتغيّر النصي text:
string text = displayLabel.Text;
ومن ثمّ تقوم بحذف آخر رقم عن طريق التابع Substring من المتغيّر text ومن ثمّ إعادة إسناد النص الناتج إلى الخاصيّة Text للصيقة displayLabel.
displayLabel.Text = text.Substring(0, text.Length - 1);
نقوم في نهاية المطاف بتفعيل زر إلغاء آخر رقم مُدخل أو تعمل على إلغاء تفعيله باستخدام طريقة جميلة تعتمد على تقييم التعبير المنطقي الموجود على يمين عامل الإسناد (=):
btnBackspace.IsEnabled = displayLabel.Text.Length > 0;
فإذا كانت اللصيقة تحتوي على رقم واحد على الأقل سيكون التعبير displayLabel.Text.Length > 0 مساويًا للقيمة true وبالتالي يتم تفعيل الزر. وإلّا سيعطي هذا التعبير القيمة false ويتم إلغاء تفعيله. حاول إجراء بعض التجارب على هذا التطبيق، ثمّ فكّر كيف يمكن تعديله لإنشاء تطبيق آلة حاسبة فعليّ، يمكنه دعم العمليّات الحسابيّة الأساسيّة الأربع على سبيل المثال.
الخلاصة
استفدنا من التطبيق الذي تناولناه في هذا الدرس، في كيفيّة استخدام مخطّط الشبكة بشكل عمليّ بغية الاستفادة من مزايا التموضع الدقيقة نسبيًّا التي يوفّرها للعناصر المرئيّة التي تُوضَع ضمنه. سنتابع العمل في الدرس التالي لنبني تطبيقًا عمليًّا مفيدًا أخرًا يستفيد أيضًا من المزايا الرائعة لمخطّط الشبكة في إنشاء مخطّط تكراري إحصائي يشبه مخطّطات الأعمدة التي من الممكن الحصول عليها من تطبيقات مكتبيّة مثل Microsoft Excel مثلًا.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.