Skip to main content

بازگرداندن یا Return اطلاعات به یک اکتیویتی والد یا parent

Return data to a parent activity

در این درس، روش‌های بازگرداندن داده از یک Activity فرزند به Activity والد در اندروید بررسی می‌شود. ابتدا نحوه استفاده از Intent برای ارسال داده تشریح شده و سپس نقش متد setResult() در تعیین RESULT_OK یا RESULT_CANCELED جهت مشخص کردن وضعیت بازگشت داده‌ها توضیح داده می‌شود. همچنین، نحوه قرار دادن داده در Intent extras و ارسال آن به والد مورد بررسی قرار گرفته و در نهایت، چگونگی دریافت نتیجه در onActivityResult() تشریح می‌شود. این درس برای توسعه‌دهندگانی که قصد دارند تعامل بین Activityها را بهینه‌سازی کنند و تجربه کاربری بهتری ارائه دهند، کاملاً ضروری است.

لینک کمکی (official link) – بازگرداندن داده به Parent Activity در اندروید|ارتباط بین Activity ها با setResult و onActivityResult

وقتی با دو تا اکتیویتی کار میکنید، میتونید داده و اطلاعاتی رو توسط پکیجی به عنوان intent extras، به اکتیویتی دوم ضمیمه کنید تا اون اطلاعات رو به اکتیویتی قبلی ببره. دقیقا مثل وقتی که داده ای رو از اکتیویتی اول به دوم میفرستادیم. برای این مدل ارسال داده، یک ثابت برای هر extra مورد نیاز هست تا هم در دسترس فرستنده و هم در دسترس گیرنده اطلاعات باشه، و همونطور که گفتم این extra یک نام مخصوص به خودشم داره، تا توسط این نام شناسایی بشه. پروژه ای که در این بخش روش کار میکنیم، Return Data هستش و من کارم رو از Main Activity شروع میکنم. و قصد دارم اینجا دو تا ثابت جدید معرفی کنم.

اول از همه سطح دسترسی اش رو private تعیین میکنم، و ثابت بودنش رو با static مشخص میکنم و همینطور میگم final باشه تا در طول برنامه قابل تغییر نباشه. لازم به ذکر هست متغیری که final تعریف بشه در طول برنامه به هیچ وجه قابل تغییر نیست و تا آخر مقدارش همونی هست که در اول تعریف میشه. جنس این متغیر integer هستش و نامش هم DETAIL_REQUEST قرار میدم. میشه گفت این ثابت یک جورایی برای هماهنگی بین دو اکتیویتی استفاده میشه. وقتی Detail Activity بارگذاری میشه، یک کد درخواستی بهش داده میشه تا وقتی از Detail Activity برمیگردم به اکتیویتی اولیه؛ معلوم بشه از کجا برگشتم به اکتیویتی اول. این مقدار میتونه هر چیزی که میخوایید باشه، ولی باید یک مقدار واحدی در این اکتیویتی باشه. بعد میخوام یک ثابت string هم ایجاد کنم که بتونه بعنوان نام extra استفاده بشه، و این متغیر برای هر دو اکتیویتی main و detail قابل دیدن هست.

خب سطح دسترسی اش رو public تعیین میکنم، و ثابت بودنش رو با static مشخص میکنم و همینطور میگم final باشه تا در طول برنامه قابل تغییر نباشه و چون این نام extra هستش، باید نوعش string باشه و اسمش رو هم RETURN_MESSAGE میذارم. میتونه هر مقداری که میخوایید داشته باشه. ولی هر چی باشه ثابت هست. و من مقدارش رو دقیقا عین اسمش تعیین میکنم. میام پایین سراغ متد On ItemClickListener که برای لیست ویو تعریف کرده بودم. این متد وقتی صدا زده میشه که کاربر یکی از آیتم های موجود در لیست رو انتخاب کنه. و با این کد start Activity، اکتیویتی دوم بار گذاری میشه و بالا میاد.

برای ایجاد هماهنگی بین دو تا اکتیویتی، میخوام این متد فراخونی رو با متد فراخونی دیگه ای با نام start ActivityForResult عوض کنم، و شی intent رو میذارم به عنوان ورودی اش باقی بمونه فقط یک ورودی دیگه بهش اضافه میکنم که مربوط به کد در خواستم میشه، که DETAIL_REQUEST هستش. و این کاری بود که در مرحله اول باید در Main Activity انجام میدادم. کمی بعد دوباره برمیگردم اینجا، ولی فعلا بریم به کلاس Detail Activity.

Detail Activity از این لایوت activity _detail استفاده میکنه، و من با فشردن کنترل یا کامند و بعدش کلیک به ترتیب در محیط ویندوز و مک به این لایوت میرم.

قصدم این هست که دکمه floating action رو تغییر شکل بدم و میخوام به جای آیکن ایمیل یک آیکن shopping cart یا سبد خرید نمایش داده بشه و میخوام وقتی کاربر این دکمه رو لمس کرد، اون محصول جاری به سبد خریدش اضافه بشه و حالا همون آیکن shopping cart ای که در ویدئوی قبلی ساختم و ازش استفاده کردم رو بکار میبرم. که در فولدر draw able هستش و اسمش هم ic _action_cart بود. ولی سایزش خیلی خوب نیست.

در واقع اگه میخواستم این برنامه رو توزیع کنم و در مارکت ها ارائه اش کنم، یک نسخه دیگه از این آیکن رو با سایز 24 در 24 دی پی ایجاد میکردم ولی الان چون داریم فقط تمرین میکنیم همین کفایت میکنه. بعدش باید کد مربوطه بهش رو در کلاس Detail Activity تغییر بدم، تا وقتی کاربر این دکمه رو لمس کرد، پیامی از Detail Activity به Main Activity فرستاده بشه. این کد این پایین هست اینجا، درست جایی که باید عملیات مربوط به event کلیک رو روی دکمه floating action button رو کنترل و تنظیم کنیم.

این کدی که برای نمایش پیام Snack bar بود رو حذف میکنم، و اینطوری با کدهای جدید جایگزینش میکنم. اول میام و یک نمونه از کلاس intent ایجاد میکنم، نام این شی جدید رو data میذارم، و وقتی معرفی اش کردم هیچ آرگومانی به سازنده اش نمیدم. چون این شی intent فقط برای این استفاده میشه که پکیجی از داده ها رو انتقال بده. بعد data .putExtra رو صدا میزنم و بعنوان ثابت ورودی، اون ثابتی که در کلاس Main Activity به نام RETURN_MESSAGE ساختم رو بهش میدم.

این نام رو واسش گذاشتم تا وقتی این رشته برمیگرده به Main Activity بتونه شناسایی اش کنه. بعد باید پیامم رو ایجاد کنم. با شی product شروع میکنم. ولی این شی برای این قسمت کدی که داخل کلاس هست قابل دیدن نیست، پس باید یک تغییر کوچیک اون بالا بدم تا قابل دیدن بشه. برمیگردم به قسمت تعریفم درست در اینجا برمیگردم، و کلمه final رو اضافه میکنم. با final تعریف کردن این متغیر، کاری میکنم که در کل کد مثلا داخل کلاس، مثل الان قابل دسترسی باشه.

و حالا میتونم product .getName رو بعنوان ورودی صدا بزنم و بعد یک رشته string دیگه به سبد خریدم اضافه کنم. در یک برنامه واقعی باید این داده در یک منبع داده ماندگار مثل دیتا بیس SQLite ذخیره بشه. بد نیست بدونید SQLite دیتابیس تعریف شده برای اندروید استودیو هستش و در برنامه های اندرویدی موقع کار با جداول و پایگاه داده از این دیتابیس استفاده میشه. ولی در این برنامه چون فقط حالت تمرینی داره من به همین اکتفا میکنم که این داده رو به Main Activity برگردونم. حالا باید به Main Activity بگیم که همه چیز اوکی هست و این داده میتونه پردازش بشه. برای اینکار متدی با نام set Result رو فراخونی میکنم، و دو تا آرگومان برای این متد بکار میبرم.

اولیش یک کد result هستش. من از یک ثابت از کلاس activity با نام RESULT_OK استفاده میکنم. توجه داشته باشید ثابت دیگه ای در لیست پیشنهادی با نام RESULT_CANCELED وجود داره. و بعد شی data بهش میدم. و درآخر متدی با نام finish رو صدا میزنم و این کار به این معنی هست که اکتیویتی جاری بسته بشه و برگردیم به اکتیویتی قبلی. خب به طور خلاصه اینجا چهار مرحله داشتیم، ساخت شی اینتنت، استفاده از پکیجی برای انتقال داده، و بعنوان دو مرحله بعدی باید بگم که اگه میخواستید بیشتر از یک extra هم برای انتقال تعریف کنید، می تونستید دو مرحله تنظیم result و متصل کردن داده به result، رو هم انجام بدید و بعد finish برای بسته شدن اکتیویتی جاری و برگشتن به اکتیویتی قبلی هم آخرین کاری بود که دیدید انجامش دادم.

حالا برمیگردم به اکتیویتی parent یا والد، یعنی کلاس Main Activity. وقتی به Main Activity برمیگردیم باید متدی با نام on ActivityResult رو فراخونی کنیم، و این یک override از متد superclass هستش. پس من ابتدای نام این متد رو تایپ میکنم و اندروید استودیو بهم پیشنهاد میده و بعد اینتر یا return رو میزنم تا کامل بشه. نیازی به فراخونی نسخه سوپر کلاس این متد ندارم پس پاکش میکنم. در این متد اول باید مطمئن بشیم که از Detail Activity ای که انتظار داشتیم از اون بیایم، اومدیم و همه چیز اوکی هستش.

حالا باید از یک کد شرطی اینجا استفاده کنم. خروجی دستور شرطی من بر اساس چک کردن این عبارت شرطی هستش که آیا requestCode == DETAIL_REQUEST هست یا نه. request Code در واقع همون اولین آرگومان این متد هستش. و این مقدار رو میام با جزییات ثابت درخواستی که از قسمت اول اکتیویتی Detail میاد مقایسه میکنم. و من باید دوباره اونو چک کنم و اگه این عبارت true بود و صدق کرد، باید یک شرط دیگه رو هم چک کنم. باید مقدار متغیر result Code هم چک بشه و مقدارش رو با ثابت RESULT_OK مقایسه میکنم.

خب حالا اگه هر دوی این شرایط برقرار باشن، میتونم data مورد نظر رو پردازش کنم. به یاد دارید که، اطلاعات رو با پیامی ثابت در return ارسال میکردیم، پس من دوباره از مقداری ثابت برای استخراج data استفاده میکنم. یک متغیر string با نام message ایجاد میکنم و با گذاشتن مساوی مقدارش رو با صدا زدن data .getStringExtra تعیین میکنم، و بعد RETURN_MESSAGE رو بعنوان ورودی بهش میدم. این Data در واقع همون سومین آرگومان داده شده به متد on ActivityResult هستش.

اینهایی که گفتم نحوه دریافت داده از Detail Activity بود. حالا میتونم از یک پیام toast ساده برای نمایش این پیام به کاربر استفاده کنم ولی به جای اون از یک چیز جذابتر استفاده میکنم. یکبار دیگه میخوام از پیام Snack bar استفاده کنم. Snackbar .make رو فراخونی میکنم. آرگومان اولش یک ویو هست و همونطور که قبلا هم اینکار رو کردم از متغیر coordinator Layout استفاده میکنم. بعد پیامی که میخوام نمایش داده بشه رو میدم و در آخر هم زمان نمایش که من از ثابت Snackbar .LENGTH_LONG استفاده میکنم.

خب حالا اگه خواستیم میتونیم عملیاتی برای پیام Snack bar اضافه کنیم. متد set Action رو فراخونی میکنم و میخوام این یک لینکی روی پیام Snack bar نمایش بده که به کاربر این امکان رو بده که قدم بعدی رو برداره و در نهایت بیاد و بعنوان یک تاییدیه نهایی باشه؛ حالا به هر روشی که دوست دارید تعریف کنید، هزینه کالاهای سبد خرید رو پرداخت و اونا رو دریافت کنه. رشته ای که قرار هست نمایش داده بشه رو Go to cart میذارم و بعد نمونه ای از واسط On ClickListener رو بعنوان ورودی اش تعریف میکنم. و همینجا ایجادش میکنم تا متد on Click تولید بشه.

و اینجا، فقط از یک پیام Toast ساده استفاده میکنم تا به کاربر بگم که اگه کارشون با این برنامه تموم شده میتونن خریدشون رو تکمیل کنن. و در آخر کد Snack bar رو با .show کامل میکنم. بیایید یک خلاصه از کارهایی که تو این قسمت انجام دادم واستون بگم. اول اومدیم چک کردیم که مطمئن بشیم از Detail Activity اومدیم و همه چیز اوکی هست. بعد رشته پیام مورد نظر رو از بسته intent به دست آوردم. بعد یک پیام Snack bar ایجاد کردم و نمایشش دادم. و همچنین با اضافه کردن action به پیام Snack bar به کاربر این امکان رو دادم که به عملیات دیگه ای بره.

و حالا آماده ام تا از کدم اجرا بگیرم. کمی میام پایین و آیتمی که مربوط به تیشرت یقه دار یعنی Polo shirt میشه رو انتخاب میکنم و وارد اکتیویتی جزییات میشم و floating action button رو میبینم که با آیکن سبد خرید نمایش داده شده. و وقتی لمسش کنم برمیگردم به main activity و پیامم رو میبینم که میگه تیشرت یقه دار به سبد خرید اضافه شد. کمی لیست رو اسکرول میکنم و آیتم دیگه ای انتخاب میکنم. ایندفه جلیقه گرم کن یا Thermal vest رو میزنم و با این آیکن خریدش می کنم و وقتی به main activity برگشتم اینبار پیام Go To Cart رو که در گوشه پایین سمت راست هست رو انتخاب میکنم، و پیام toast رو مشاهده میکنم.

از اینجا اگه خواستید باز هم یک اکتیویتی دیگه بسازید، میتونید صفحه ای برای سبد خرید ایجاد کنید و منبع ذخیره سازی داده ثابتی برای برنامه تون ایجاد کنید. و یک برنامه تجارت الکترونیکی کامل بسازید. بنابراین بر اساس همه توضیحات مفصلی که در این بخش دادم میتونید اطلاعاتی رو بین اکتیویتی ها مثل main و detail رد و بدل کنید. و برای اینکار اینتنت ها میتونن پکیجی از داده ها رو بین اکتیویتی ها به جریان بندازن.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دوره ها
درس ها
Tha PMIS
طهاکو من
0