<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های الیاس محمدی</title>
        <link>https://virgool.io/feed/@elias.mohammady91</link>
        <description>Android Developer With a Passion to Learn</description>
        <language>fa</language>
        <pubDate>2026-06-16 14:57:38</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/41904/avatar/XUnFOH.png?height=120&amp;width=120</url>
            <title>الیاس محمدی</title>
            <link>https://virgool.io/@elias.mohammady91</link>
        </image>

                    <item>
                <title>الگوهای طراحی در اندروید (فصل اول - اپیزود 1) : Observer Pattern</title>
                <link>https://virgool.io/@elias.mohammady91/%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7%DB%8C-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%AF%D8%B1-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-1-observer-pattern-fqnk1riryylr</link>
                <description>بعد از مدتی که برنامه نویسی رو شروع می‌کنید اصطلاحاتی از با تجربه‌های این حوزه می‌شنویم یا می‌خوانیم.یکی از چیزهایی که زیاد شنیده می‌شود Design Patterns و یا در فارسی الگوهای طراحی هستند.در سری مقالات الگوهای طراحی در اندروید در تلاشم تا Design Pattern های مهم رو بشناسیم و کاربرد آنها را در برنامه نویسی اندروید ببینیم.هدف این است که ببینیم بطور مثلا الگو Observer چیست؟چطور پیاده سازی می‌شود و در نهایت در برنامه نویسی اندروید کجا قابل استفاده است.پس با من همراه باشید.تعریف Observer Patternدر کتاب مقدس و بسیار عالی Head First Design Patterns تعریف زیر برای الگو Observer آمده است:Defines a one-to-many dependency between objects so that when one object changes state,all its dependents are notified and updates automatically!!اگر بخواهیم این تعریف را تفسیر کرده و به زبان فارسی بنویسیم، می‌توان گفت: وقتی یک شی یا موجودیت تغییر می‌کند و سایر موجودیت ها و شی‌ها خواستار این هستند که تغییرات آن شی را بدانند.در دنیا واقعی اگر بخواهیم مثالی بزنیم، این الگو را می‌توان اینطور یافت که شما عضو دنبال‌کنندگان یا Subscriberهای یک کانال خاص در YouTube می‌شو‌ید.وقتی در کانال ویدیو جدیدی اضافه شود به شما خبر داده خواهد شد.شما در هر لحظه که بخواهید می‌توانید اشتراک خود و یا کانالی که دنبال می‌کنید را عوض کنید.همچنین کانال هیچ وابستگی به دنبال‌کنندگانش ندارد و کار خود را انجام می‌دهد.در دنیای اندروید هم اگر بخواهیم مثالی بزنیم،فرض کنید برنامه شما یک شی دارد که عملیات دریافت اطلاعات را از وب سرویس انجام می‌دهد.سایر اشیا دوست دارند،وقتی این شی اطلاعات را دریافت کرد،این تغییرات و اطلاعات را بدانند.اجزا کلی الگو Observerبا توجه به تعاریف بالا،در این الگو دو بازیگر اصلی داریم: 1- دنبال کننده  یا Observer/Subscriber  2- دنبال شونده یا Observable/Subjectوظیفه Observable این است که تغییرات وضعیت خود را به Observer اطلاع دهد.در مقابل ، وظیفه Observer این است که خود را به عنوان دنبال کننده حالت Observable معرفی کرده،تغییرات را دریافت کند و عملیات لازم را انجام دهد.در ادامه برای فهم بهتر موضوع و همچنین آشنایی بیشتر، نحوه پیاده سازی این الگو را بررسی می‌کنیم.با من همراه باشید.پیاده سازی Observableهر Observable دو کار اصلی باید انجام دهد: اول اینکه راهی فراهم سازد تا Observer ها خود را معرفی کنند و دوم ،راهی فراهم سازد تا تغییرات به Observer ها اطلاع داده شود.پس برای شروع یک interface می‌سازیم که بصورت زیر می‌باشد و هر کلاسی خواست Observable باشد باید این interface را پیاده سازی کند:پیاده سازی Observerوظیفه Observer این است که تغییرات را دریافت کند.پس متدی باید داشته باشد که تغییرات را دریافت کرده و عملیات لازم را انجام دهد.پیاده سازی این بخش نیز از طریق interface می‌باشد و هر کلاسی که بخواهد Observer باشد،باید این interface را پیاده سازی کند:پیاده سازی کلاس‌های مورد نظرابتدا کلاس Subject که IObservable را پیاده سازی کرده به صورت زیر می‌سازیم:کلاس Subjectپیاده‌سازی متدهای مربوط به کلاس IObservableدر تصویر فوق،در متد addObserver ، ما Observer ها را به لیست خود اضافه می‌کنیم و در متد notifyChanges، برای تمام آنها،متد updateState ، صدا زده می‌شود تا تغییرات را دریافت کرده و آنطور که دوست دارند با تغییرات برخورد کنند.حال نوبت به کلاس Subcriber می‌رسد.در تصویر زیر نحوه پیاده سازی این کلاس را می‌بینید:کلاس Subscriber که از IObserver مشتق شده است!!در پیاده سازی کلاس Subscriber،آنچه حائز اهمیت است این است که این کلاس در متد سازنده خود،یک IObservable می‌گیرد و با صدا زدن متد addObserver خود را به عنوان دنبال کننده معرفی می‌کند.در نهایت در متد updateState ،ما عملیات لازم را انجام می‌دهیم.بطور مثال اینجا با فراخوانی متد getFullTitle، تغییرات را مشاهده می‌کنیم.تست برنامه برای تست برنامه یک اکتیویتی میسازیم.از هر کلاس شی ساخته و در نهایت حالت شی subject را تغییر می‌دهیم و تغییرات را در logcat برنامه میبینیم:ساخت اکتیویتی و شی های مورد نظرساخت thread برای تغییر حالت subject دقت شود در تصویر فوق بعد از تغییر حالت mySubject، به مدت 2 ثانیه Thread  به حالت sleep رفته و با صدا زدن متد notifyChanges، تغییرات برای mySubscriber ارسال می‌شود.نتیجه خروجی در LogCatدر قسمت بعد کاربرد این الگو را در برنامه نویسی اندروید می‌بینیم.امیدوارم این مطلب مفید بوده باشد.برای بررسی بیشتر، از گیت هاب من به آدرس زیر می‌توانید کدهای را دریافت کنید.  https://github.com/eliasmohammadi/Android_design_pattern </description>
                <category>الیاس محمدی</category>
                <author>الیاس محمدی</author>
                <pubDate>Wed, 07 Aug 2019 16:41:53 +0430</pubDate>
            </item>
                    <item>
                <title>من تو را می‌بینم...دیتا را لود کن:در باب متد SetUserVisibleHint</title>
                <link>https://virgool.io/@elias.mohammady91/%D9%85%D9%86-%D8%AA%D9%88-%D8%B1%D8%A7-%D9%85%DB%8C%D8%A8%DB%8C%D9%86%D9%85%D8%AF%DB%8C%D8%AA%D8%A7-%D8%B1%D8%A7-%D9%84%D9%88%D8%AF-%DA%A9%D9%86%D8%AF%D8%B1-%D8%A8%D8%A7%D8%A8-%D9%85%D8%AA%D8%AF-setuservisiablehint-jjgn2cgpc3yk</link>
                <description>Photo by Shahadat Shemul on Unsplashدر اکثر برنامه‌های موبایل،از TabLayout و ViewPager  استفاده می‌کنیم.بعضی پروژه‌‌ها تعداد تب‌های زیاد و بعضی دیگر تعداد تب‌های کمتری دارند.مسئلهاگر تعداد تب‌ها زیاد باشد و بطور مثال در هر تب بخواهیم یک سری دیتا از وب‌ سرویس‌های مختلف بگیریم و نمایش دهیم،احتمالا با مشکل performance مواجه می‌شویم و شاهد بارگذاری‌های طولانی خواهیم بود.مشکلی که در پروژه‌ای با 12 تب مختلف برای من اتفاق افتاد.راه حلبرای حل این مشکل لازم بود،اطلاعات زمانی دریافت شود که کاربر وارد تب مربوطه شده است.پس بریم ببینیم چطور میشود این راه حل را پیاده سازی کرد.در حالت عادی،فرض کنیم ما 3 تب داریم.اگر MainActivity را باز کنیم،طبق تصویر زیر متوجه می‌شویم که FragmentOne و FragmentTwo همزمان در حالت OnCreateView هستند.یعنی اگر در OnCreateView بخواهیم دیتا بگیریم(کاری که من انجام دادم)،2 تب همزمان عملیات دریافت دیتا را انجام می‌دهند.برای حل این مشکل از متدی به اسم setUserVisibleHint استفاده می‌کنیم.این متد توسط فریمورک اندروید صدا زده می‌شود و جز متد‌های کلاس Fragment می‌باشد.وظیفه این متد این است که مشخص می‌کند Fragment مورد نظر دیده شده است یا خیر!دقت شود که این متد قبل متد OnCreateView فراخوانی شده و اجرا می‌شود.در تصویر زیر یک نمونه ساده از پیاده سازی این متد نمایش داده شده است.اگر مقدار isVisibleToUser درست باشد عبارت &quot;I&#x27;m Visible For User...Load Data Now&quot; نمایش داده می‌شود و در غیر اینصورت عبارت &quot;I&#x27;m not Visible&quot; در لاگ نمایش داده می‌شود.اگر برنامه را اجرا کنیم و در تب 1 باشیم،چون کاربر در حال مشاهده تب 1 است،با تصویر زیر مواجه می‌شویم:حال اگر به تب 2 یا 3 بریم،دیگر تب 1 قابل مشاهده نیست و لاگ ما به فرم زیر درمی‌آید:پس برای بهبود performance، من از این متد استفاده کردم و زمانی که مقدار isVisibleToUser  برابر True بود،عملیات درخواست دیتا از Api را انجام دادم.با این روش خدا رو شکر پروژه به سرانجام رسید.دوستان عزیز اگر تجربه مشابهی دارید با من به اشتراک بذارید.ممنون از توجه شما.</description>
                <category>الیاس محمدی</category>
                <author>الیاس محمدی</author>
                <pubDate>Sat, 20 Jul 2019 00:46:35 +0430</pubDate>
            </item>
                    <item>
                <title>چالشی از جنس CustomRecyclerView</title>
                <link>https://virgool.io/@elias.mohammady91/%DA%86%D8%A7%D9%84%D8%B4%DB%8C-%D8%A7%D8%B2-%D8%AC%D9%86%D8%B3-customrecyclerview-ioq6x7rtkqcv</link>
                <description>Photo by Clark Tibbs on Unsplashبرای پروژه ای مجبور بودم از تعداد زیادی لیست استفاده کنم.تقریبا در هر صفحه یک لیست برای نمایش داشتم که با صفحه‌های دیگر شباهت داشت.اول تصمیم گرفتم که یک کلاس Adapter بسازم و تمام Adapter ها از این کلاس ارث بری کنند و هربار خواستم RecyclerView  بسازم،داخل کد جاوا Adapter مربوطه رو new کنم و ادامه ماجرا...با خودم گفتم جالب میشه اگه خود RecyclerView می‌توست دیتا مورد نظر رو پیدا کنه و لازم نباشه داخل کد جاوا بهش دیتا بدیم.یعنی داخل خود تگ RecyclerView داخل کد xml مسیر دیتا رو بهش میدادیم و لیست پر میشد و دیگه لازم نبود داخل اکتیویتی RecyclerView رو پیدا کنیم و لیست مربوطه رو بهش پاس بدیم.پس تصمیم گرفتم یک CustomRecyclerView بسازم که مسیر مورد نظر برای تولید دیتا رو بگیره و لیست پر بشه.با این کار خیلی کارم سریع میشد.فقط تگ رو اضافه می‌کردم و آدرس یک متد رو بهش میدادم و هروقت اکتیویتی اجرا میشد لیست پر شده و درست اجرا میشد.پس دست به کار شدم.در ادامه یک نمونه ساده از نحوه پیاده سازی رو برای دوستان می‌نویسم.قدم اول : ساخت attrsداخل پوشه values یک فایل با نام attrs.xml ایجاد می‌کنیم و بصورت زیر ویژگی‌های موردنظر روبهش میدیم.این ویژگی‌ها زمانی که از تگ میخواهیم استفاده کنیم،قابل دسترسی هستند و مشابه width یا هر ویژگی دیگه‌ای می‌باشند.قدم دوم: ساخت Adapter و ViewHolderدر این مرحله یک adapter ساخته و براساس طرح مورد نظر ViewHolder و Layout  را طراحی کنید.قدم سوم: ساخت یک کلاس DataProviderدر این مرحله یک کلاس به اسم DataProvider  ساختم که متدی با نام getRows داره که برای ما دیتا و آیتم های مورد نظر برای نمایش در لیست را تولید می‌کند.در تصویر زیر یک نمونه ازین متد که فقط لیستی از رشته ها تولید می‌کند رو می‌تونید ببینید.قدم چهارم: ساخت کلاس CustomRecyclerViewحالا بخش اصلی کارمون شروع میشه.یک کلاس با نام CustomRecyclerView می‌سازیم که از کلاس RecyclerView ارث بری کرده است.همچنین یک متد به اسم render ساختم که مراحل خواندن ویژگی ها و دیتا را انجام دهد.ابتدا با گرفتن متن برگشتی از ویژگی dataBinder و جدا کردن آن، نام کلاس و متد مورد نظر برای گرفتن دیتا را بدست آوردم.در قدم بعدی با استفاده ازReflection کلاس و متد مورد نظر رو پیدا کردم و متد رو صدا زدم و خروجی متد رو داخل یک لیست از جنس رشته ریختم.در نهایت Adapter را که ساخته بودم با این لیست پر کردم.قدم پنجم: اضافه کردن تگ CustomRecyclerViewحالا وقتشه که این تگ رو به xml اضافه کنم.پس به layout  مورد نظر میرم و این تگ رو به صورت زیر اضافه می‌کنم و در قسمت dataBinder بصورت زیر آدرس کلاس و متد رو میدهم و در قسمت packageName آدرس پکیج که کلاس درون آن قرار دارد:app:dataBinder=&quot;DataProvider/getRows&quot;
app:packageName=&quot;com.eliasmohammadi.customrecyclerview.Model&quot;وقتی برنامه رو اجرا کنیم،می‌بینیم که بدون اینکه داخل MainActivity کدی نوشته باشیم،لیست ما پر میشه و نمایش داده میشه.خروجی برنامه را در تصویر زیر رو ببینید:در پایان دوستان اگر تجربه مشابهی دارید،ممنون میشم با من به اشتراک بذارید.در ضمن لینک سورس پروژه این مقاله رو میتونید از گیت هاب من به آدرس زیر دریافت کنید.ممنون از توجه شما https://github.com/eliasMohammady/CustomRecyclerView_virgool </description>
                <category>الیاس محمدی</category>
                <author>الیاس محمدی</author>
                <pubDate>Sat, 13 Jul 2019 01:40:06 +0430</pubDate>
            </item>
                    <item>
                <title>جادوی گریدل برای برنامه نویسان اندروید:متغیرها</title>
                <link>https://virgool.io/devAndroid/%D8%AC%D8%A7%D8%AF%D9%88%DB%8C-%DA%AF%D8%B1%DB%8C%D8%AF%D9%84-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%D8%A7%D9%86-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF%D9%85%D8%AA%D8%BA%DB%8C%D8%B1%D9%87%D8%A7-ip5ivuodsirw</link>
                <description>Image From Unsplashدر gradle می‌تونیم دو نوع متغیر تعریف کنیم.این دو نوع به صورت buildConfigField و resValue هستند.buildConfigField  رو وقتی تعریف می‌کنیم داخل کلاس BuildConfig  یک متغیر استاتیک تعریف میشه که  داخل کد جاوا قابل دسترسی هست.در عوض resValue بصورت کد جاوا تولید نمیشه بلکه به صورت resource می‌باشد.خب کاربرد این متغیرها چیه؟به عنوان یک تجربه کاری،اپلیکیشن من قرار بود برای نسخه debug که به واحد تست تحویل داده می‌شد،از وب سرویس‌های سرور A استفاده کنه و برای نسخه release که به کارفرما تحویل می‌دادیم از سرور B دیتا بگیره.در ابتدا اومدم یک کلاس Constant به صورت زیر ساختم:وقتی می‌خواستم به کارفرما اپلیکیشن رو بدم،آدرس release رو از حالت کامنت در می‌آوردم و خروجی می‌گرفتم.خب کار اشتباهی بود ولی کار راه انداز بود.البته احتمال خطا بالا بود.بعد از مدتی با متغیر‌های gradle آشنا شدم و در فایل build.gradle  به صورت زیر اول دو نوع buildType ساختم:یکی برای release و  یکی برای debug.در مرحله بعدی یک متغیر به اسم BASE_URL تعریف کردم به این صورت:وقتی gradle رو sync کردم،داخل کلاس BuildConfig دیدم متغیر BASE_URL اضافه شده.حالا برای دسترسی به این متغیر کافی بود بصورت زیر ازش استفاده کنم و در کنارش از منو BuildVariants نوع buildType  مورد نظر رو انتخاب کنیم:دیگه دردسر کامنت کردن برطرف شد و مطمئن بودم نسخه ای که به کارفرما میدم،با آدرس درست خروجی گرفته شده است.از کاربردهای دیگه ، مثلا API_KEY رو میشه داخل فایل gradle ذخیره کرد و مثلا داخل AndroidManifest بهش دسترسی داشت،به این شکل:تعریف در فایل گریدلاستفاده در فایل manifest در پایان ممنون میشم دوستان تجربیاتتون را با من به اشتراک بذارید و اگر تجربه مشابه و کاربرد مفیدی برای متغیرهای گریدل دارید بیان کنید.ممنون از توجه شما.</description>
                <category>الیاس محمدی</category>
                <author>الیاس محمدی</author>
                <pubDate>Thu, 11 Jul 2019 02:48:18 +0430</pubDate>
            </item>
            </channel>
</rss>