سنعرض لك كيفية إنشاء تطبيق حاسبة Kotlin tip بسيط. بشكل أكثر تحديدًا ، Kotlin 1.3.21 ، Android 4 ، Android Studio 3. ستكون المقالة مثيرة للاهتمام ، أولاً وقبل كل شيء ، لأولئك الذين يبدأون رحلتهم في تطوير تطبيقات Android. انها تسمح لك لفهم ما وكيف يعمل داخل التطبيق.
هذه الآلة الحاسبة مفيدة عندما تحتاج إلى حساب مقدار النصائح من شركة قررت قضاء بعض الوقت في مطعم أو مقهى. بالطبع ، ليس كل شيء ولا يترك دائمًا للنادلين على الشاي ، فهذا تقليد غربي ، لكن عملية تطوير مثل هذا التطبيق مثيرة للاهتمام على أي حال.
نذكرك: لجميع قراء "Habr" - خصم بقيمة 10،000 روبل عند التسجيل في أي دورة تدريبية في Skillbox باستخدام الرمز "Habr" الترويجي.
توصي Skillbox بما يلي: دورة عملية "Mobile Developer PRO .
إليك ما يبدو عليه التطبيق في العملية:

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


الإجراء الأول هو
تنزيل أساسيات المشروع . افتحه في Android Studio 3.0 أو إصدار أحدث. نحن نبني المشروع ونطلقه ونرى شاشة بيضاء. كل شيء على ما يرام ، يجب أن يكون كذلك.


يتم توضيح تصرفات المستخدم في المشروع بترتيب زمني بحيث يكون كل شيء واضحًا. لمشاهدته ، افتح عرض -> أداة Windows -> TODO.
ندرس المشروع ونفتح colours.xml لتقييم لوحة الألوان. يتم وضع البيانات النصية (التوقيعات) في strings.xml ، وهناك العديد من قوالب الخطوط في styles.xml.
تطوير قسم التكلفة
افتح activity_main.xml وأضف الكود أدناه في LinearLayout (# 1):
<TextView android:id="@+id/expensePerPersonTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="30dp" style="@style/h1Bold" android:textColor="@color/colorAccent" android:text="0"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="25dp" style="@style/h2" android:textColor="@color/colorAccent" android:text="@string/perPersonStaticText"/>
يمكنك الآن تخصيص نمط دليل القيم أو اللعب باستخدام الألوان باستخدام
أداة material.io .
الآن يبدو المشروع كالتالي:
كما ترون ، يتم حساب التكاليف وفقًا للبيانات التي يقوم بها المستخدم.قسم تطوير الحساب
أضف الكود أدناه في LinearLayout بعد قسم النفقات (# 2):
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@color/colorAccent"> <! — TODO #3: Build Bill Section → … </LinearLayout>
أغلق LinearLayout بعد قائمة TODOs ، ثم أضف رمزًا جديدًا ، ضعه داخل LinearLayout (# 3):
<TextView android:layout_margin="15dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/colorWhite" style="@style/h4" android:text="@string/billStaticText"/> <EditText android:id="@+id/billEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/colorWhite" android:inputType="numberDecimal" android:maxLines="1" style="@style/h2Bold" android:text="0"/>
نظرًا لأن المهمة الرئيسية للتطبيق هي حساب التكاليف الفردية لكل من المشاركين في التجمعات في المطعم ، يتم تشغيل القيمة الرئيسية بواسطة costPerPersonTextView.
يقيد EditText الإدخال في سطر واحد ؛ يجب أن يكون لهذه المعلمة قيمة inputType NumberDecimal.
نبدأ المشروع للاختبار وإدخال معلمات الضرر الكلي (الكؤوس ، الألواح المكسورة ، إلخ)تطوير قسم "الناس والنصائح"
لإضافة تحديد حجم الصوت ، أدخل الكود أدناه في قسم LinearLayout الجديد (رقم 4):
<TextView android:layout_margin="15dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/colorWhite" style="@style/h4" android:text="@string/tipStaticText"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageButton android:id="@+id/subtractTipButton" style="@style/operationButton" android:layout_marginLeft="20dp" android:layout_marginStart="20dp" android:src="@drawable/subtract"/> <TextView android:id="@+id/tipTextView" android:layout_margin="15dp" android:layout_width="0dp" android:layout_height="wrap_content" android:textColor="@color/colorWhite" android:layout_weight="1" style="@style/h2Bold" android:text="20%"/> <ImageButton android:id="@+id/addTipButton" style="@style/operationButton" android:layout_marginEnd="20dp" android:layout_marginRight="20dp" android:src="@drawable/add"/> </LinearLayout>
هذا القسم من الكود ضروري لحساب دقيق لكمية الحافة. القيمة الافتراضية للنص هي 20. يتم توفير ImageButtons مع الرموز في المجلد مع أذونات الكتابة.
نحن ننسخ القسم بالكامل ونضيف ما يلي (# 5):
- ImageButton ids (subtractPeopleButton، addPeopleButton)
- معرفات TextView (numberOfPeopleStaticText ، numberOfPeopleTextView)
- نص افتراضي لـ numberOfPeopleTextView (يجب أن يكون 4).

الآن عند بدء تشغيل التطبيق ، من الممكن إضافة مبلغ الفاتورة ، تعمل أزرار "إضافة / طرح" أيضًا ، ولكن لم يحدث شيء حتى الآن.
إضافة المشاهدات
افتح MainActivity.kt وأضف هذا إلى وظيفة initViews (# 6):
private fun initViews() { expensePerPersonTextView = findViewById(R.id.expensePerPersonTextView) billEditText = findViewById(R.id.billEditText) addTipButton = findViewById(R.id.addTipButton) tipTextView = findViewById(R.id.tipTextView) subtractTipButton = findViewById(R.id.subtractTipButton) addPeopleButton = findViewById(R.id.addPeopleButton) numberOfPeopleTextView = findViewById(R.id.numberOfPeopleTextView) subtractPeopleButton = findViewById(R.id.subtractPeopleButton)
الانتهاء من الأزرار
لإضافة دعم النقر على زر ، ننفذ طريقة العرض على مستوى الفصل الدراسي. OnClickListener (# 7):
class MainActivity : AppCompatActivity(), View.OnClickListener {
لن يعمل تجميع المشروع في الوقت الحالي ، فأنت بحاجة إلى تنفيذ بضع خطوات إضافية (# 8):
override fun onClick(v: View?) { when (v?.id) { R.id.addTipButton -> incrementTip() R.id.subtractTipButton -> decrementTip() R.id.addPeopleButton -> incrementPeople() R.id.subtractPeopleButton -> decrementPeople() } }
من حيث الأزرار والمفاتيح في Kotlin ، كل شيء منظم بشكل رائع! أضف الكود أدناه لجميع وظائف الزيادة والتناقص
(# 9 - # 12):
private fun incrementTip() { if (tipPercent != MAX_TIP) { tipPercent += TIP_INCREMENT_PERCENT tipTextView.text = String.format("%d%%", tipPercent) } } private fun decrementTip() { if (tipPercent != MIN_TIP) { tipPercent -= TIP_INCREMENT_PERCENT tipTextView.text = String.format("%d%%", tipPercent) } } private fun incrementPeople() { if (numberOfPeople != MAX_PEOPLE) { numberOfPeople += PEOPLE_INCREMENT_VALUE numberOfPeopleTextView.text = numberOfPeople.toString() } } private fun decrementPeople() { if (numberOfPeople != MIN_PEOPLE) { numberOfPeople -= PEOPLE_INCREMENT_VALUE numberOfPeopleTextView.text = numberOfPeople.toString() } }
هنا ، يحمي الرمز وظائف الزيادة مع الحد الأقصى للقيم (MAX_TIP & MAX_PEOPLE). بالإضافة إلى ذلك ، يحمي الرمز وظائف التناقص مع الحد الأدنى من القيم (MIN_TIP & MIN_PEOPLE).
قم الآن بربط الأزرار مع المستمعين في وظيفة initViews (# 13):
private fun initViews() { ... addTipButton.setOnClickListener(this) subtractTipButton.setOnClickListener(this) addPeopleButton.setOnClickListener(this) subtractPeopleButton.setOnClickListener(this)

يمكنك الآن إضافة الضرر الكلي والنصائح وعدد المشاركين في الاجتماع. حسنا ، الآن أهم شيء ...
قسم التكاليف
هذا الرمز يحسب التكاليف (# 14):
private fun calculateExpense() { val totalBill = billEditText.text.toString().toDouble() val totalExpense = ((HUNDRED_PERCENT + tipPercent) / HUNDRED_PERCENT) * totalBill val individualExpense = totalExpense / numberOfPeople expensePerPersonTextView.text = String.format("$%.2f", individualExpense) }
حسنًا ، هنا تسمى الوظيفة التي تجعل من الممكن مراعاة عدد الأشخاص في الشركة وحساب التلميح (# 15):
private fun incrementTip() { … } private fun decrementTip() { … } private fun incrementPeople() { … } private fun decrementPeople() { … }
نطلق التطبيق. يبدو ويعمل بشكل جيد. ولكن يمكن أن يكون أفضل.
إذا حاولت حذف مبلغ الفاتورة ، ثم قمت بزيادة عدد النصائح أو الأصدقاء ، فسوف يتعطل التطبيق بسبب عدم وجود تحقق من تكلفة الصفر بعد. علاوة على ذلك ، إذا حاولت تغيير مبلغ الفاتورة ، فلن يتم تحديث التكاليف.
الخطوات النهائية
إضافة TextWatcher (# 16):
class MainActivity : AppCompatActivity(), View.OnClickListener, TextWatcher {
ثم قمنا بتضمين مستمع billEditText (رقم 17):
billEditText.addTextChangedListener(this)
بالإضافة إلى ذلك ، أضف التعليمات البرمجية لتنفيذ TextWatcher (# 18):
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { if (!billEditText.text.isEmpty()) { calculateExpense() } } override fun afterTextChanged(s: Editable?) {} override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

حسنا ، الآن كل شيء يعمل على الاطلاق! تهانينا ، لقد كتبت "حاسبة البقشيش" الخاصة بك على Kotlin.

توصي Skillbox بما يلي: