شرایط در کاتلین - قسمت 2

در این کد لبه، تصاویر تاس را به برنامه اندرویدی Dice Roller موجود خود اضافه خواهید کرد. حتماً ابتدا کدهای قبلی را در مورد ساخت پایه برنامه Dice Roller تکمیل کنید.

به جای نمایش مقدار تاس ریخته شده در TextView ، برنامه شما تصویر تاس مناسب را برای تعداد اضلاع ریخته شده نمایش می دهد. این یک تجربه کاربری بسیار بصری و بهبود یافته برای برنامه شما خواهد بود.

پیوندی برای دانلود تصاویر تاس در اختیار شما قرار می گیرد و آنها را به عنوان منابع در برنامه خود اضافه می کنید. برای نوشتن کدی که از کدام تصویر تاس استفاده کنید، از دستور when در Kotlin استفاده خواهید کرد.

پیش نیازها

  • برنامه Android Create a Dice Roller را با یک کد لبه دکمه تکمیل کرد.
  • قادر به نوشتن دستورات جریان کنترل ( if / else , when دستورات).
  • قادر به به روز رسانی رابط کاربری برنامه بر اساس ورودی کاربر (تغییر فایل MainActivity.kt ).
  • قادر به اضافه کردن یک شنونده کلیکی به یک Button.
  • امکان افزودن منابع تصویری به برنامه اندروید.

چیزی که یاد خواهید گرفت

  • نحوه به روز رسانی ImageView در حین اجرای برنامه
  • چگونه رفتار برنامه خود را بر اساس شرایط مختلف سفارشی کنید (با استفاده از عبارت when ).

چیزی که خواهی ساخت

  • اپلیکیشن اندروید Dice Roller که Button ای برای انداختن تاس و به روز رسانی تصویر روی صفحه دارد.

آنچه شما نیاز دارید

  • یک رایانه با Android Studio نصب شده است.
  • اتصال به اینترنت برای دانلود تصاویر تاس.

در این کار، TextView را در طرح خود با ImageView جایگزین می‌کنید که تصویری از نتیجه پرتاب تاس را نشان می‌دهد.

برنامه Dice Roller را باز کنید

  1. برنامه Dice Roller را از برنامه Create a Dice Roller اندروید با یک دکمه در Android Studio باز کرده و اجرا کنید.
    برنامه باید شبیه این باشد.

  1. activity_main.xml ( app > res > layout > activity_main.xml ) را باز کنید.
    با این کار ویرایشگر Layout باز می شود.

TextView را حذف کنید

  1. در Layout Editor ، TextView را در Component Tree انتخاب کنید.
  1. کلیک راست کرده و Delete را انتخاب کنید یا کلید Delete را فشار دهید.
  2. فعلاً هشدار روی Button را نادیده بگیرید. در مرحله بعد آن را برطرف خواهید کرد.

یک ImageView به طرح‌بندی اضافه کنید

  1. ImageView را از پالت به نمای طراحی بکشید و آن را بالای Button قرار دهید.

  1. در گفتگوی انتخاب یک منبع ، آواتارها را در زیر نمونه داده انتخاب کنید. این تصویر موقتی است که تا زمانی که تصاویر تاس را در کار بعدی اضافه نکنید، استفاده خواهید کرد.

  1. OK را فشار دهید. نمای طراحی اپلیکیشن شما باید به این شکل باشد.

  1. در Component Tree ، متوجه دو خطا خواهید شد. Button به صورت عمودی محدود نمی شود و ImageView نه به صورت عمودی و نه افقی محدود می شود.

Button به صورت عمودی محدود نمی شود زیرا TextView را که در زیر آن در ابتدا قرار داشت حذف کردید. اکنون باید ImageView و Button زیر آن را قرار دهید.

ImageView و دکمه را در موقعیت قرار دهید

شما باید ImageView را به صورت عمودی در مرکز صفحه نمایش قرار دهید، صرف نظر از اینکه Button در کجا قرار دارد.

  1. محدودیت های افقی را به ImageView اضافه کنید. سمت چپ ImageView را به لبه چپ ConstraintLayout والد متصل کنید.
  2. سمت راست ImageView را به لبه سمت راست والد متصل کنید.
    با این کار ImageView به صورت افقی در مرکز والد قرار می گیرد.

  1. یک محدودیت عمودی به ImageView اضافه کنید و قسمت بالایی ImageView را به بالای والد متصل کنید.
    ImageView به بالای ConstraintLayout می کشد.
  2. یک محدودیت عمودی به Button اضافه کنید، بالای Button را به پایین ImageView متصل کنید.
    Button زیر ImageView به سمت بالا حرکت می کند.
  3. حالا دوباره ImageView را انتخاب کنید و یک محدودیت عمودی اضافه کنید که پایین ImageView را به پایین والد متصل می کند.
    این کار ImageView را به صورت عمودی در ConstraintLayout متمرکز می کند.

اکنون همه هشدارها در مورد محدودیت ها باید از بین بروند.

پس از همه اینها، نمای طراحی باید به این شکل باشد، با ImageView در مرکز و Button درست زیر آن.

ممکن است متوجه هشداری در ImageView در درخت کامپوننت شوید که می‌گوید توضیح محتوا را به ImageView خود اضافه کنید. در حال حاضر نگران این هشدار نباشید زیرا بعداً در نرم افزار کد، توضیحات محتوای ImageView را بر اساس تصویر تاسی که نمایش می دهید تنظیم خواهید کرد. این تغییر در کد Kotlin انجام خواهد شد.

در این کار، تعدادی تصویر تاس را دانلود کرده و به برنامه خود اضافه خواهید کرد.

دانلود تصاویر تاس

  1. این URL را باز کنید تا یک فایل فشرده از تصاویر تاس را در رایانه خود بارگیری کنید. صبر کنید تا دانلود کامل شود.
  2. فایل را در رایانه خود پیدا کنید (احتمالاً در پوشه دانلودها ).
  3. روی فایل فشرده دوبار کلیک کنید تا بسته بندی شود. این یک پوشه DiceImages جدید ایجاد می کند که حاوی 6 فایل تصویری تاس است و مقادیر تاس را از 1 تا 6 نمایش می دهد.

تصاویر تاس را به برنامه خود اضافه کنید

  1. در Android Studio، روی View > Tool Windows > Resource Manager در منوها کلیک کنید یا روی زبانه Resource Manager در سمت چپ پنجره Project کلیک کنید.
  2. روی + زیر Resource Manager کلیک کنید و Import Drawables را انتخاب کنید. این یک مرورگر فایل را باز می کند.

  1. 6 فایل تصویری تاس را پیدا و انتخاب کنید. می توانید اولین فایل را انتخاب کنید، سپس در حالی که کلید Shift را نگه داشته اید، فایل های دیگر را انتخاب کنید.
  2. روی Open کلیک کنید.
  1. روی Next و سپس Import کلیک کنید تا تأیید کنید که می خواهید این 6 منبع را وارد کنید.

  1. اگر فایل ها با موفقیت وارد شدند، 6 تصویر باید در لیست Drawable برای برنامه شما ظاهر شوند.

کارت خوب بود! در کار بعدی، از این تصاویر در اپلیکیشن خود استفاده خواهید کرد.

مهم! - می توانید با شناسه منابع به این تصاویر در کد Kotlin خود مراجعه کنید:

  • R.drawable.dice_1
  • R.drawable.dice_2
  • R.drawable.dice_3
  • R.drawable.dice_4
  • R.drawable.dice_5
  • R.drawable.dice_6

نمونه تصویر آواتار را جایگزین کنید

  1. در ویرایشگر طراحی ، ImageView را انتخاب کنید.
  2. در Attributes در قسمت Declared Attributes ، ویژگی ابزار srcCompat را پیدا کنید که روی تصویر آواتار تنظیم شده است.

به یاد داشته باشید که ویژگی tools srcCompat از تصویر ارائه شده فقط در نمای طراحی اندروید استودیو استفاده می کند. تصویر تنها در حین ساختن برنامه برای توسعه دهندگان نمایش داده می شود، اما زمانی که برنامه را در شبیه ساز یا دستگاه اجرا می کنید، دیده نمی شود.

  1. روی پیش نمایش کوچک آواتار کلیک کنید. این یک گفتگو برای انتخاب یک منبع جدید برای استفاده برای این ImageView باز می کند.

  1. dice_1 را انتخاب کنید و روی OK کلیک کنید.

وای ImageView کل صفحه را اشغال می کند.

بعد، عرض و ارتفاع ImageView را تنظیم می‌کنید، بنابراین Button پنهان نمی‌شود.

  1. در پنجره Attributes در زیر ابزارک Constraints ، ویژگی‌های layout_width و layout_height را پیدا کنید. آنها در حال حاضر روی wrap_content تنظیم شده اند، به این معنی که ImageView به اندازه محتوای (تصویر منبع) داخل آن بلند و گسترده خواهد بود.
  2. در عوض، عرض ثابت 160dp و ارتفاع ثابت 200dp را در ImageView تنظیم کنید. Enter را فشار دهید.

    ImageView اکنون بسیار کوچکتر شده است.


ممکن است متوجه شوید که Button کمی بیش از حد به تصویر نزدیک است.

  1. با تنظیم آن در Constraint Widget ، یک حاشیه بالا به دکمه 16dp اضافه کنید.

پس از به روز رسانی نمای طراحی ، برنامه بسیار بهتر به نظر می رسد!

با کلیک روی دکمه، تصویر تاس را تغییر دهید

طرح بندی اصلاح شده است، اما کلاس MainActivity برای استفاده از تصاویر تاس باید به روز شود.

در حال حاضر یک خطا در برنامه در فایل MainActivity.kt وجود دارد. اگر سعی کنید برنامه را اجرا کنید، این خطای ساخت را مشاهده خواهید کرد:

این به این دلیل است که کد شما همچنان به TextView که از طرح بندی حذف کرده اید ارجاع می دهد.

  1. MainActivity.kt باز کنید ( app > java > com.example.diceroller > MainActivity.kt )

کد به R.id.textView اشاره دارد، اما Android Studio آن را تشخیص نمی دهد.

  1. در rollDice() هر کدی را که به TextView اشاره دارد انتخاب کنید و آن را حذف کنید.
// Update the TextView with the dice roll
val resultTextView: TextView = findViewByID(R.id.textView)
resultTextView.text = dice.roll().toString()
  1. هنوز در rollRice() یک متغیر جدید به نام diceImage از نوع ImageView ایجاد کنید. آن را برابر با ImageView از طرح بندی تنظیم کنید. از متد findViewById() استفاده کنید و شناسه منبع ImageView ، R.id.imageView را به عنوان آرگومان ورودی ارسال کنید.
val diceImage: ImageView = findViewById(R.id.imageView)

اگر می‌خواهید چگونه شناسه منبع دقیق ImageView را بفهمید، شناسه بالای پنجره ویژگی‌ها را بررسی کنید.

وقتی به این شناسه منبع در کد کاتلین مراجعه می‌کنید، مطمئن شوید که آن را دقیقاً به همان شکل تایپ کرده‌اید (با حروف کوچک i، بزرگ V، بدون فاصله). در غیر این صورت اندروید استودیو خطا نشان می دهد.

  1. این خط کد را اضافه کنید تا آزمایش کنید که با کلیک روی دکمه می توانید ImageView را به درستی به روز کنید. تاس انداختن همیشه "2" نخواهد بود، بلکه فقط از تصویر dice_2 برای اهداف آزمایشی استفاده کنید.
diceImage.setImageResource(R.drawable.dice_2)

این کد setImageResource() را در ImageView فراخوانی می کند و شناسه منبع را برای تصویر dice_2 می کند. با این کار ImageView روی صفحه به روز می شود تا تصویر dice_2 نمایش داده شود.

rollDice() اکنون باید به شکل زیر باشد:

private fun rollDice() {
    val dice = Dice(6)
    val diceRoll = dice.roll()
    val diceImage: ImageView = findViewById(R.id.imageView)
    diceImage.setImageResource(R.drawable.dice_2)
}
  1. برنامه خود را اجرا کنید تا مطمئن شوید که بدون خطا اجرا می شود.

برنامه باید با یک صفحه خالی به جز دکمه Roll شروع شود.

پس از ضربه زدن روی دکمه، یک تصویر تاس که مقدار 2 را نشان می دهد ظاهر می شود. آره!!

شما توانستید بر اساس ضربه زدن روی دکمه تصویر را تغییر دهید! نزدیک تر میشی!

واضح است که نتیجه تاس همیشه 2 نخواهد بود. از منطق جریان کنترلی که در آزمایشگاه کد افزودن رفتار شرطی برای پرتاب تاس های مختلف یاد گرفتید استفاده کنید تا بسته به تاس تصادفی، تصویر تاس مناسب روی صفحه نمایش داده شود.

قبل از اینکه شروع به تایپ کد کنید، با نوشتن کد شبه که توضیح می دهد چه اتفاقی باید بیفتد، به طور مفهومی در مورد نحوه عملکرد برنامه فکر کنید. مثلا:

اگر کاربر یک عدد 1 انداخت، سپس تصویر dice_1 را نمایش دهید.

اگر کاربر یک عدد 2 انداخت، سپس تصویر dice_2 را نمایش دهید.

و غیره...

شبه کد بالا را می توان با عبارات if / else در Kotlin بر اساس مقدار تاس ریخته نوشت.

if (diceRoll == 1) {
   diceImage.setImageResource(R.drawable.dice_1)
} else if (diceRoll == 2) {
   diceImage.setImageResource(R.drawable.dice_2)
}
 ...

اگرچه نوشتن if / else برای هر مورد بسیار تکراری می شود. همین منطق را می توان به سادگی با یک عبارت when بیان کرد. این مختصرتر است (کد کمتر)! از این روش در برنامه خود استفاده کنید.

when (diceRoll) {
   1 -> diceImage.setImageResource(R.drawable.dice_1)
   2 -> diceImage.setImageResource(R.drawable.dice_2)
   ...

متد rollDice() را به روز کنید

  1. در rollDice() هر بار خط کدی را که شناسه منبع تصویر را روی تصویر dice_2 می دهد حذف کنید.
diceImage.setImageResource(R.drawable.dice_2)
  1. آن را با یک عبارت when جایگزین کنید که ImageView را بر اساس مقدار diceRoll به روز می کند.
   when (diceRoll) {
       1 -> diceImage.setImageResource(R.drawable.dice_1)
       2 -> diceImage.setImageResource(R.drawable.dice_2)
       3 -> diceImage.setImageResource(R.drawable.dice_3)
       4 -> diceImage.setImageResource(R.drawable.dice_4)
       5 -> diceImage.setImageResource(R.drawable.dice_5)
       6 -> diceImage.setImageResource(R.drawable.dice_6)
   }

وقتی تغییرات را تمام کردید، متد rollDice() باید به این شکل باشد.

private fun rollDice() {
   val dice = Dice(6)
   val diceRoll = dice.roll()

   val diceImage: ImageView = findViewById(R.id.imageView)

   when (diceRoll) {
       1 -> diceImage.setImageResource(R.drawable.dice_1)
       2 -> diceImage.setImageResource(R.drawable.dice_2)
       3 -> diceImage.setImageResource(R.drawable.dice_3)
       4 -> diceImage.setImageResource(R.drawable.dice_4)
       5 -> diceImage.setImageResource(R.drawable.dice_5)
       6 -> diceImage.setImageResource(R.drawable.dice_6)
   }
}
  1. برنامه را اجرا کنید. با کلیک بر روی دکمه Roll تصویر تاس به مقادیر دیگر به غیر از 2 تغییر می کند. کار می کند!

کد خود را بهینه کنید

اگر می خواهید کد کوتاه تری بنویسید، می توانید کد زیر را تغییر دهید. هیچ تاثیر قابل مشاهده ای برای کاربر برنامه شما ندارد، اما باعث می شود کد شما کوتاه تر و کمتر تکرار شود.

ممکن است متوجه شده باشید که diceImage.setImageResource() 6 بار در دستور when شما ظاهر می شود.

when (diceRoll) {
    1 -> diceImage.setImageResource(R.drawable.dice_1)
    2 -> diceImage.setImageResource(R.drawable.dice_2)
    3 -> diceImage.setImageResource(R.drawable.dice_3)
    4 -> diceImage.setImageResource(R.drawable.dice_4)
    5 -> diceImage.setImageResource(R.drawable.dice_5)
    6 -> diceImage.setImageResource(R.drawable.dice_6)
}

تنها چیزی که بین هر مورد تغییر می کند، شناسه منبعی است که استفاده می شود. این بدان معناست که شما می توانید یک متغیر برای ذخیره شناسه منبع برای استفاده ایجاد کنید. سپس می توانید diceImage.setImageResource() را فقط یک بار در کد خود فراخوانی کنید و شناسه منبع صحیح را ارسال کنید.

  1. کد بالا را با کد زیر جایگزین کنید.
val drawableResource = when (diceRoll) {
   1 -> R.drawable.dice_1
   2 -> R.drawable.dice_2
   3 -> R.drawable.dice_3
   4 -> R.drawable.dice_4
   5 -> R.drawable.dice_5
   6 -> R.drawable.dice_6
}

diceImage.setImageResource(drawableResource)

یک مفهوم جدید در اینجا این است که عبارت when می تواند در واقع یک مقدار را برگرداند. با این قطعه کد جدید، عبارت when شناسه منبع صحیح را برمی گرداند که در متغیر drawableResource ذخیره می شود. سپس می توانید از آن متغیر برای به روز رسانی منبع تصویر نمایش داده شده استفاده کنید.

  1. توجه داشته باشید when اکنون با رنگ قرمز زیر آن خط کشیده شده است. اگر نشانگر خود را روی آن نگه دارید، یک پیام خطایی خواهید دید: «وقتی عبارت باید جامع باشد، شاخه «دیگر» لازم را اضافه کنید .

خطا به این دلیل است که مقدار عبارت when به drawableResource اختصاص داده شده است، بنابراین when باید جامع باشد - باید تمام موارد ممکن را مدیریت کند تا همیشه یک مقدار برگردانده شود، حتی اگر به یک تاس 12 وجهی تغییر دهید. استودیو پیشنهاد می کند یک شاخه else اضافه کنید. می توانید با تغییر قاب 6 به else این مشکل را برطرف کنید. موارد 1 تا 5 یکسان است، اما بقیه موارد از جمله 6 توسط else رسیدگی می شود.

val drawableResource = when (diceRoll) {
   1 -> R.drawable.dice_1
   2 -> R.drawable.dice_2
   3 -> R.drawable.dice_3
   4 -> R.drawable.dice_4
   5 -> R.drawable.dice_5
   else -> R.drawable.dice_6
}

diceImage.setImageResource(drawableResource)
  1. برنامه را اجرا کنید تا مطمئن شوید هنوز درست کار می کند. حتما آن را به اندازه کافی تست کنید تا مطمئن شوید که تمام اعداد با تصاویر تاس 1 تا 6 ظاهر می شوند.

یک توضیح محتوای مناسب را در ImageView تنظیم کنید

اکنون که شماره رول شده را با یک تصویر جایگزین کرده‌اید، صفحه‌خوان‌ها دیگر نمی‌توانند بفهمند چه عددی رول شده است. برای رفع این مشکل، پس از به‌روزرسانی منبع تصویر، توضیحات محتوای ImageView را به‌روزرسانی کنید. توضیحات محتوا باید شرح متنی باشد از آنچه در ImageView نشان داده شده است تا خوانندگان صفحه بتوانند آن را توصیف کنند.

diceImage.contentDescription = diceRoll.toString()

صفحه خوان ها می توانند این توضیحات محتوا را با صدای بلند بخوانند، بنابراین اگر تاس تصویر "6" روی صفحه نمایش داده شود، توضیحات محتوا با صدای بلند به عنوان "6" خوانده می شود.

تجربه راه اندازی مفیدتری ایجاد کنید

وقتی کاربر برای اولین بار برنامه را باز می کند، برنامه خالی است (به جز دکمه Roll )، که عجیب به نظر می رسد. کاربران ممکن است ندانند چه انتظاری داشته باشند، بنابراین وقتی برای اولین بار برنامه را شروع می‌کنید و Activity را ایجاد می‌کنید، رابط کاربری را تغییر دهید تا یک تاس تصادفی نمایش داده شود. سپس کاربران بیشتر متوجه می شوند که با ضربه زدن روی دکمه Roll یک تاس ریخته می شود.

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val rollButton: Button = findViewById(R.id.button)
   rollButton.setOnClickListener { rollDice() }

   // Do a dice roll when the app starts
   rollDice()
}

کد خود را کامنت کنید

برای توضیح آنچه در کدی که نوشته‌اید اتفاق می‌افتد، چند نظر به کد خود اضافه کنید.

بعد از اینکه همه این تغییرات را rollDice() شما ممکن است به این شکل باشد.

/**
* Roll the dice and update the screen with the result.
*/
private fun rollDice() {
   // Create new Dice object with 6 sides and roll the dice
   val dice = Dice(6)
   val diceRoll = dice.roll()

   // Find the ImageView in the layout
   val diceImage: ImageView = findViewById(R.id.imageView)

   // Determine which drawable resource ID to use based on the dice roll
   val drawableResource = when (diceRoll) {
       1 -> R.drawable.dice_1
       2 -> R.drawable.dice_2
       3 -> R.drawable.dice_3
       4 -> R.drawable.dice_4
       5 -> R.drawable.dice_5
       else -> R.drawable.dice_6
   }

   // Update the ImageView with the correct drawable resource ID
   diceImage.setImageResource(drawableResource)

   // Update the content description
   diceImage.contentDescription = diceRoll.toString()
}

برای فایل کامل MainActivity.kt ، کد راه حل را در GitHub که در زیر پیوند داده شده است، ببینید.

آفرین برای تکمیل برنامه Dice Roller! اکنون می توانید این برنامه را به شب بازی بعدی با دوستان خود بیاورید!

کد راه حل برای این کد لبه در پروژه و ماژول نشان داده شده در زیر است.

برای دریافت کد این کد لبه از گیت هاب و باز کردن آن در اندروید استودیو، موارد زیر را انجام دهید.

  1. اندروید استودیو را راه اندازی کنید.
  2. در پنجره خوش آمدید به Android Studio ، روی بررسی پروژه از کنترل نسخه کلیک کنید.
  3. Git را انتخاب کنید.

  1. در گفتگوی Clone Repository ، URL کد ارائه شده را در کادر URL قرار دهید.
  2. روی دکمه Test کلیک کنید، منتظر بمانید و مطمئن شوید که یک حباب بازشو سبز وجود دارد که می گوید اتصال موفقیت آمیز است.
  3. به صورت اختیاری، دایرکتوری را به چیزی متفاوت از پیش فرض پیشنهادی تغییر دهید.

  1. روی Clone کلیک کنید. Android Studio شروع به واکشی کد شما می کند.
  2. در پنجره بازشو Checkout from Version Control ، روی Yes کلیک کنید.

  1. منتظر بمانید تا Android Studio باز شود.
  2. ماژول صحیح را برای راه‌انداز یا کد راه‌حل Codelab خود انتخاب کنید.

  1. روی دکمه Run کلیک کنید برای ساخت و اجرای کد شما
  • از setImageResource() برای تغییر تصویری که در ImageView نمایش داده می شود استفاده کنید
  • از دستورات جریان کنترلی مانند عبارات if / else یا عبارات when برای رسیدگی به موارد مختلف در برنامه خود استفاده کنید، به عنوان مثال، تصاویر مختلف را در شرایط مختلف نشان دهید.

موارد زیر را انجام دهید:

  1. تاس دیگری را به برنامه اضافه کنید، به طوری که یک دکمه Roll 2 نتیجه تاس بدهد. چه تعداد ImageViews در طرح بندی خود نیاز دارید؟ چه تاثیری روی کد MainActivity.kt خواهد داشت؟

کارتو چک کن:

برنامه تمام شده شما باید بدون خطا اجرا شود و دو تاس را نشان دهد.