در این کد لبه، تصاویر تاس را به برنامه اندرویدی 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 را باز کنید
- برنامه Dice Roller را از برنامه Create a Dice Roller اندروید با یک دکمه در Android Studio باز کرده و اجرا کنید.
برنامه باید شبیه این باشد.
-
activity_main.xml
( app > res > layout > activity_main.xml ) را باز کنید.
با این کار ویرایشگر Layout باز می شود.
TextView را حذف کنید
- در Layout Editor ،
TextView
را در Component Tree انتخاب کنید.
- کلیک راست کرده و Delete را انتخاب کنید یا کلید
Delete
را فشار دهید. - فعلاً هشدار روی
Button
را نادیده بگیرید. در مرحله بعد آن را برطرف خواهید کرد.
یک ImageView به طرحبندی اضافه کنید
-
ImageView
را از پالت به نمای طراحی بکشید و آن را بالایButton
قرار دهید.
- در گفتگوی انتخاب یک منبع ، آواتارها را در زیر نمونه داده انتخاب کنید. این تصویر موقتی است که تا زمانی که تصاویر تاس را در کار بعدی اضافه نکنید، استفاده خواهید کرد.
- OK را فشار دهید. نمای طراحی اپلیکیشن شما باید به این شکل باشد.
- در Component Tree ، متوجه دو خطا خواهید شد.
Button
به صورت عمودی محدود نمی شود وImageView
نه به صورت عمودی و نه افقی محدود می شود.
Button
به صورت عمودی محدود نمی شود زیرا TextView
را که در زیر آن در ابتدا قرار داشت حذف کردید. اکنون باید ImageView
و Button
زیر آن را قرار دهید.
ImageView و دکمه را در موقعیت قرار دهید
شما باید ImageView
را به صورت عمودی در مرکز صفحه نمایش قرار دهید، صرف نظر از اینکه Button
در کجا قرار دارد.
- محدودیت های افقی را به
ImageView
اضافه کنید. سمت چپImageView
را به لبه چپConstraintLayout
والد متصل کنید. - سمت راست
ImageView
را به لبه سمت راست والد متصل کنید.
با این کارImageView
به صورت افقی در مرکز والد قرار می گیرد.
- یک محدودیت عمودی به
ImageView
اضافه کنید و قسمت بالاییImageView
را به بالای والد متصل کنید.
ImageView
به بالایConstraintLayout
می کشد. - یک محدودیت عمودی به
Button
اضافه کنید، بالایButton
را به پایینImageView
متصل کنید.
Button
زیرImageView
به سمت بالا حرکت می کند. - حالا دوباره
ImageView
را انتخاب کنید و یک محدودیت عمودی اضافه کنید که پایینImageView
را به پایین والد متصل می کند.
این کارImageView
را به صورت عمودی درConstraintLayout
متمرکز می کند.
اکنون همه هشدارها در مورد محدودیت ها باید از بین بروند.
پس از همه اینها، نمای طراحی باید به این شکل باشد، با ImageView
در مرکز و Button
درست زیر آن.
ممکن است متوجه هشداری در ImageView
در درخت کامپوننت شوید که میگوید توضیح محتوا را به ImageView
خود اضافه کنید. در حال حاضر نگران این هشدار نباشید زیرا بعداً در نرم افزار کد، توضیحات محتوای ImageView
را بر اساس تصویر تاسی که نمایش می دهید تنظیم خواهید کرد. این تغییر در کد Kotlin انجام خواهد شد.
در این کار، تعدادی تصویر تاس را دانلود کرده و به برنامه خود اضافه خواهید کرد.
دانلود تصاویر تاس
- این URL را باز کنید تا یک فایل فشرده از تصاویر تاس را در رایانه خود بارگیری کنید. صبر کنید تا دانلود کامل شود.
- فایل را در رایانه خود پیدا کنید (احتمالاً در پوشه دانلودها ).
- روی فایل فشرده دوبار کلیک کنید تا بسته بندی شود. این یک پوشه
DiceImages
جدید ایجاد می کند که حاوی 6 فایل تصویری تاس است و مقادیر تاس را از 1 تا 6 نمایش می دهد.
تصاویر تاس را به برنامه خود اضافه کنید
- در Android Studio، روی View > Tool Windows > Resource Manager در منوها کلیک کنید یا روی زبانه Resource Manager در سمت چپ پنجره Project کلیک کنید.
- روی + زیر Resource Manager کلیک کنید و Import Drawables را انتخاب کنید. این یک مرورگر فایل را باز می کند.
- 6 فایل تصویری تاس را پیدا و انتخاب کنید. می توانید اولین فایل را انتخاب کنید، سپس در حالی که کلید
Shift
را نگه داشته اید، فایل های دیگر را انتخاب کنید. - روی Open کلیک کنید.
- روی Next و سپس Import کلیک کنید تا تأیید کنید که می خواهید این 6 منبع را وارد کنید.
- اگر فایل ها با موفقیت وارد شدند، 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
نمونه تصویر آواتار را جایگزین کنید
- در ویرایشگر طراحی ،
ImageView
را انتخاب کنید. - در Attributes در قسمت Declared Attributes ، ویژگی ابزار srcCompat را پیدا کنید که روی تصویر آواتار تنظیم شده است.
به یاد داشته باشید که ویژگی tools srcCompat از تصویر ارائه شده فقط در نمای طراحی اندروید استودیو استفاده می کند. تصویر تنها در حین ساختن برنامه برای توسعه دهندگان نمایش داده می شود، اما زمانی که برنامه را در شبیه ساز یا دستگاه اجرا می کنید، دیده نمی شود.
- روی پیش نمایش کوچک آواتار کلیک کنید. این یک گفتگو برای انتخاب یک منبع جدید برای استفاده برای این
ImageView
باز می کند.
-
dice_1
را انتخاب کنید و روی OK کلیک کنید.
وای ImageView
کل صفحه را اشغال می کند.
بعد، عرض و ارتفاع ImageView
را تنظیم میکنید، بنابراین Button
پنهان نمیشود.
- در پنجره Attributes در زیر ابزارک Constraints ، ویژگیهای layout_width و layout_height را پیدا کنید. آنها در حال حاضر روی wrap_content تنظیم شده اند، به این معنی که
ImageView
به اندازه محتوای (تصویر منبع) داخل آن بلند و گسترده خواهد بود. - در عوض، عرض ثابت 160dp و ارتفاع ثابت 200dp را در
ImageView
تنظیم کنید. Enter را فشار دهید.
ImageView
اکنون بسیار کوچکتر شده است.
ممکن است متوجه شوید که Button
کمی بیش از حد به تصویر نزدیک است.
- با تنظیم آن در Constraint Widget ، یک حاشیه بالا به دکمه 16dp اضافه کنید.
پس از به روز رسانی نمای طراحی ، برنامه بسیار بهتر به نظر می رسد!
با کلیک روی دکمه، تصویر تاس را تغییر دهید
طرح بندی اصلاح شده است، اما کلاس MainActivity
برای استفاده از تصاویر تاس باید به روز شود.
در حال حاضر یک خطا در برنامه در فایل MainActivity.kt
وجود دارد. اگر سعی کنید برنامه را اجرا کنید، این خطای ساخت را مشاهده خواهید کرد:
این به این دلیل است که کد شما همچنان به TextView
که از طرح بندی حذف کرده اید ارجاع می دهد.
-
MainActivity.kt
باز کنید ( app > java > com.example.diceroller > MainActivity.kt )
کد به R.id.textView
اشاره دارد، اما Android Studio آن را تشخیص نمی دهد.
- در
rollDice()
هر کدی را که بهTextView
اشاره دارد انتخاب کنید و آن را حذف کنید.
// Update the TextView with the dice roll
val resultTextView: TextView = findViewByID(R.id.textView)
resultTextView.text = dice.roll().toString()
- هنوز در
rollRice()
یک متغیر جدید به نامdiceImage
از نوعImageView
ایجاد کنید. آن را برابر باImageView
از طرح بندی تنظیم کنید. از متدfindViewById()
استفاده کنید و شناسه منبعImageView
،R.id.imageView
را به عنوان آرگومان ورودی ارسال کنید.
val diceImage: ImageView = findViewById(R.id.imageView)
اگر میخواهید چگونه شناسه منبع دقیق ImageView
را بفهمید، شناسه بالای پنجره ویژگیها را بررسی کنید.
وقتی به این شناسه منبع در کد کاتلین مراجعه میکنید، مطمئن شوید که آن را دقیقاً به همان شکل تایپ کردهاید (با حروف کوچک i، بزرگ V، بدون فاصله). در غیر این صورت اندروید استودیو خطا نشان می دهد.
- این خط کد را اضافه کنید تا آزمایش کنید که با کلیک روی دکمه می توانید
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)
}
- برنامه خود را اجرا کنید تا مطمئن شوید که بدون خطا اجرا می شود.
برنامه باید با یک صفحه خالی به جز دکمه 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() را به روز کنید
- در
rollDice()
هر بار خط کدی را که شناسه منبع تصویر را روی تصویرdice_2
می دهد حذف کنید.
diceImage.setImageResource(R.drawable.dice_2)
- آن را با یک عبارت
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)
}
}
- برنامه را اجرا کنید. با کلیک بر روی دکمه 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()
را فقط یک بار در کد خود فراخوانی کنید و شناسه منبع صحیح را ارسال کنید.
- کد بالا را با کد زیر جایگزین کنید.
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
ذخیره می شود. سپس می توانید از آن متغیر برای به روز رسانی منبع تصویر نمایش داده شده استفاده کنید.
- توجه داشته باشید
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 تا 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! اکنون می توانید این برنامه را به شب بازی بعدی با دوستان خود بیاورید!
کد راه حل برای این کد لبه در پروژه و ماژول نشان داده شده در زیر است.
برای دریافت کد این کد لبه از گیت هاب و باز کردن آن در اندروید استودیو، موارد زیر را انجام دهید.
- اندروید استودیو را راه اندازی کنید.
- در پنجره خوش آمدید به Android Studio ، روی بررسی پروژه از کنترل نسخه کلیک کنید.
- Git را انتخاب کنید.
- در گفتگوی Clone Repository ، URL کد ارائه شده را در کادر URL قرار دهید.
- روی دکمه Test کلیک کنید، منتظر بمانید و مطمئن شوید که یک حباب بازشو سبز وجود دارد که می گوید اتصال موفقیت آمیز است.
- به صورت اختیاری، دایرکتوری را به چیزی متفاوت از پیش فرض پیشنهادی تغییر دهید.
- روی Clone کلیک کنید. Android Studio شروع به واکشی کد شما می کند.
- در پنجره بازشو Checkout from Version Control ، روی Yes کلیک کنید.
- منتظر بمانید تا Android Studio باز شود.
- ماژول صحیح را برای راهانداز یا کد راهحل Codelab خود انتخاب کنید.
- روی دکمه Run کلیک کنید برای ساخت و اجرای کد شما
- از setImageResource() برای تغییر تصویری که در
ImageView
نمایش داده می شود استفاده کنید - از دستورات جریان کنترلی مانند عبارات
if / else
یا عباراتwhen
برای رسیدگی به موارد مختلف در برنامه خود استفاده کنید، به عنوان مثال، تصاویر مختلف را در شرایط مختلف نشان دهید.
موارد زیر را انجام دهید:
- تاس دیگری را به برنامه اضافه کنید، به طوری که یک دکمه Roll 2 نتیجه تاس بدهد. چه تعداد
ImageViews
در طرح بندی خود نیاز دارید؟ چه تاثیری روی کدMainActivity.kt
خواهد داشت؟
کارتو چک کن:
برنامه تمام شده شما باید بدون خطا اجرا شود و دو تاس را نشان دهد.