<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>پست‌های انتشارات جامعه برنامه نویسان اندروید</title>
        <link>https://virgool.io/AndroidPPub/feed</link>
        <description>اندروید زیر ذره بین</description>
        <language>fa</language>
        <pubDate>2026-06-10 16:07:20</pubDate>
        <image>
            <url>https://files.virgool.io/upload/publication/6zn94a8gwql0/1pmrxt.png</url>
            <title>جامعه برنامه نویسان اندروید</title>
            <link>https://virgool.io/AndroidPPub</link>
        </image>

                    <item>
                <title>اموزش کامل Navigation component در اندروید- قسمت اول</title>
                <link>https://virgool.io/AndroidPPub/%D8%A7%D9%85%D9%88%D8%B2%D8%B4-%DA%A9%D8%A7%D9%85%D9%84-navigation-component-%D8%AF%D8%B1-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-ipeoerx2thyl</link>
                <description>یکی از باحال ترین و هیجان انگیز ترین بخش های jetpack چیزی نیست جز navigation component که در واقع مجموعه ای از کتابخانه ها , پلاگین ها و ابزار هاست که &#x27;جا به جایی&#x27; رو متحول میکنه. دیگه نیازی نیست با چیز هایی که خیلی رو اعصاب هستند مثل FragmentManager و ... سر و کار داشته باشید و کار خیلی سریع تر و تمیز تر انجام میشهگوگل توصیه میکند که از الگو single activity پیروی کنیم. یعنی فقط یک اکتیویتی داشته باشیم و بقیه کار ها  با فرگمنت ها انجام بشه. به خاطر همین ما مبنا اموزش رو همین قرار دادیم ولی اگر چند اکتیویتی هم داشته باشید فرقی نمیکند . مفاهیم یکی است . ولی ما مثل حرفه ای ها از همین الگو استفاده می کنیم:)واقعا لازمه بگم که نگذارید تعاریف قلمبه این مبحث شما را از پا در اورد. با کمی تمرین و مطالعه خیلی راحت برایتان جا می افتد.اول یک مقایسه بین روش قدیمی و navigation داشته باشیم. یک جور هایی اگر روش قدیمی رو بلد باشید کار کردن با navigation زیاد براتون سخت نیست. فرض کنید یک اکتیویتی با تعدادی فرگمنت داشته باشیم که نیاز داریم بین این فرگمنت ها جا به جا شویم.در روش قدیمی در layout اکتیویتی باید که FrameLayout تعریف میکردیم که فرگمنت ها در اون جا به جا میشدند. جا به جایی این فرگمنت ها هم نیازمند استفاده از FragmentManager و ... بود. میتونستیم با fragment argument یک سری اطلاعات رو بین فرگمنت ها رد و بدل کنیم و ...و اما در navigation کار خیلی راحت تر است ولی ارتباطی هم بین تعاریف navigation و روش قدیمی وجود داره که اگر برای اولین بار از اون استفاده میکنید ممکنه به درک شما کمک کنه. در navigation هم باید یک navHost تعریف کنیم که فرگمنت ها (یا اکتیویتی ها که بهشون میگیم مقصد) در اون جا به جا میشوند. مثل FrameLayout. هر navHost به یک نقشه(navigation graph) متصل میشه که اون نقشه میگه که چه مقصد هایی در اون navHost وجود داره و کاربر چطور میتونه بین اونها جا به جابه بشه(action). کنترل هر navHost رو یک navContorller به عهده میگیره که مثل FragmentManager میمونه با این تفاوت که هرnavHost یک navController اختصاصی داره.پس با سه عنصر مهم navigation component اشنا شدیم:۱- navHost: یک container یا نگه دارنده یک سری مقصد . مقصد ها در navHost جا به جا میشوند درست مثل FrameLayout.۲− navigation graph : یک نقشه از همه مقصد ها و البته همه مسیر هایی که کاربر میتواند طی انها بین مقصد ها جا به جا شود(که به ان action میگوییم) . این نقشه را به یک navHost میدهیم و navHost از طریق این نقشه میفهمه کاربر کجا ها میتونه بره.۳−action: هر اکشن میگه که کاربر میتونه از فلان مقصد به یک مقصد دیگه بره. هر وقت این اکشن رو فراخوانی میکنیم واقعا بین ان دو مقصد جابه جا میشویم.و اما navigation graph که به اون نقشه میگیم از دو بخش تشکیل شده:۱- مقصد یا destination : هم فرگمنت یا اکتیویتی که کاربر میتواند به انجا برود. صفحه هایی که در نقشه میبینید(شماره یک) مقصد های ما هستند.(فرگمنت یا اکتیویتی که کاربر میتواند به انجا برود)۲− action: فلش هایی که مسیرهایی که  کاربر میتواند بین مقصد ها طی کند را مشخص میکند.این نقشه شکل کلی برنامه ما را مشخص میکند. چند مقصد داریم که طی action ها بین هم جابه میشوند.حرف زدن بسه. بریم سراغ کار عملیچیکار میکنیم؟اگر بخوام کل مراحل رو خلاصه وار توضیح بدم(همه مراحل به صورت مفصل بررسی میشوند. فقط این رو داشته باشید بد نیست) :اول یک اکتیویتی را به عنوان navHost انتخاب میکنیم. مثل اینکه قبلا به layout اکتیویتی یک FrameLayout اضافه میکردیم. مقصد ها در این navHost جا به جا میشوند.بعد یک یا چند فرگمنت که میخواهیم در این navHost وجود داشته باشند را میسازیم.سپس یک نقشه میسازیم, همه این مقصد ها را به ان اضافه میکنیم و با ابزار های گرافیکی action ها (مسیر هایی که کاربر میتواند طی ان جا به جا شود) را رسم میکنیم.بعد از بر اساس فعالیت های کاربر مثل کلیک روی یک دگمه یکی از action ها رو فرا میخوانیم - هر اکشن میگه از فلان مقصد به مقصد دیگر برو- و طی ان میتوانیم اطلاعات جا به جا کنیم و کار های معمولیاول dependency بعد کاربرای اینکه با navigation کار کنید به این dependency های نیاز دارید:dependencies {
  def nav_version = &amp;quot2.3.0-alpha06&amp;quot

  // Java language implementation
  implementation &amp;quotandroidx.navigation:navigation-fragment:$nav_version&amp;quot
  implementation &amp;quotandroidx.navigation:navigation-ui:$nav_version&amp;quot

  // Kotlin
  implementation &amp;quotandroidx.navigation:navigation-fragment-ktx:$nav_version&amp;quot
  implementation &amp;quotandroidx.navigation:navigation-ui-ktx:$nav_version&amp;quot

  // Dynamic Feature Module Support
  implementation &amp;quotandroidx.navigation:navigation-dynamic-features-fragment:$nav_version&amp;quot

  // Testing Navigation
  androidTestImplementation &amp;quotandroidx.navigation:navigation-testing:$nav_version&amp;quot
}×× ممکن است وقتی این مقاله را میخوانید ورژن جدیدی منتشر شده باشدساخت navigation graphاین نقشه یک نوع جدید resource است که همه مقصد ها و action ها در اون تعریف میشه. ظاهر گرافیکی این نقشه اینطوریه:و مثل layout ها میتونیم هم با نوشتن تگ های XML و به صورت گرافیکی با Navigation Editor اون رو تغییر بدیم. برای ساخت نقشه این مسیر رو دنبال کنیدروی پوشه res راست کلیک کنید و New &gt; Android Resource File را انتخاب کنید. صفحه New Resource File ظاهر میشود.یک اسم مثل &quot;nav_graph&quot; انتخاب کنید.در بخش Resource type , و Navigation را برگزینید.وقتی برای اولین بار این کار را کردید به صورت خودکار یک پوشه به اسم navigation ایجاد میشود و nav_graph در ان قرار میگیرد. وقتی نقشه ساخته شد اندروید استودیو نقشه را در Navigation Editor باز میکند که در ان میتوانید به صورت گرافیکی نقشه را تغییر دهید. اگر تب text را انتخاب کنید با همچین چیزی مواجه میشوید:&lt;?xml version=&amp;quot1.0&amp;quot encoding=&amp;quotutf-8&amp;quot?&gt;
&lt;navigation xmlns:android=&amp;quothttp://schemas.android.com/apk/res/android&amp;quot
            xmlns:app=&amp;quothttp://schemas.android.com/apk/res-auto&amp;quot
            android:id=&amp;quot@+id/nav_graph&amp;quot&gt;

&lt;/navigation&gt; همانطور که میبینیدroot element  همه نقشه ها &lt;navigation&gt; است. این فایل با تگ ها &lt;destination&gt; و &lt;action&gt; پر خواهد شد.اضافه کردن NavHost به اکتیویتی فرض کنید NavHost همان FrameLayout است. باید ان را به layout اکتیویتی اضافه کنیم.&lt;?xml version=&amp;quot1.0&amp;quot encoding=&amp;quotutf-8&amp;quot?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android=&amp;quothttp://schemas.android.com/apk/res/android&amp;quot
    xmlns:app=&amp;quothttp://schemas.android.com/apk/res-auto&amp;quot
    xmlns:tools=&amp;quothttp://schemas.android.com/tools&amp;quot
    android:layout_width=&amp;quotmatch_parent&amp;quot
    android:layout_height=&amp;quotmatch_parent&amp;quot
    tools:context=&amp;quot.MainActivity&amp;quot&gt;

    &lt;androidx.appcompat.widget.Toolbar
        .../&gt;

    &lt;fragment
        android:id=&amp;quot@+id/nav_host_fragment&amp;quot
        android:name=&amp;quotandroidx.navigation.fragment.NavHostFragment&amp;quot
        android:layout_width=&amp;quot0dp&amp;quot
        android:layout_height=&amp;quot0dp&amp;quot
        app:layout_constraintLeft_toLeftOf=&amp;quotparent&amp;quot
        app:layout_constraintRight_toRightOf=&amp;quotparent&amp;quot
        app:layout_constraintTop_toTopOf=&amp;quotparent&amp;quot
        app:layout_constraintBottom_toBottomOf=&amp;quotparent&amp;quot

        app:defaultNavHost=&amp;quottrue&amp;quot
        app:navGraph=&amp;quot@navigation/nav_graph&amp;quot /&gt;

    &lt;com.google.android.material.bottomnavigation.BottomNavigationView
        .../&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;اینجا سه تا نکته وجود داره:با android:name مشخص میکنیم که navHost ما از چه نوعی خواهد بود. در اینجا گفتیم NavHostFragment یعنی این navHost چند فرگمنت را در خود نگه میدارد. معمولا این چیزیه که نیاز دارید.با app:defaultNavHost=&quot;true&quot;  گفتیم که وقتی  کاربر دکمه برگشت(back button) را فشار داد یهو از برنامه نپر بیرون برای خودت.با app:navGraph=&quot;@navigation/nav_graph&quot; هم ادرس نقشه مون رو مشخص کردیم. داریم بهش میگیم: داداش این navHost پیرو این نقشه است, فلان تعداد مقصد داره که با این action ها بین هم میتونن جا به جا بشن.چطور یک مقصد اضافه کنیمتوی navigation editor(همون محیط گرافیکی) میتونیم با استفاده از آیکون پایین یکی از فرگمنت یا اکتیویتی هایی که درست کردیم رو به عنوان مقصد تعیین کنیم. بعد یک پیش نمایش از ظاهر فرگمنت یا اکتیویتی به نمایش در میاد که میتونیم اون رو جا به کنیم و نقشه خودمون رو بسازیم.با انتخاب این ایکون در بالای navigation editor یک مقصد اضافه میکنیم.اتصال مقصد ها یا همون actionتوی navigation editor روی یک مقصد کلیک کنید . دایره ای توخالی یا همچین چیزی رو باید ببینید:اون دایره رو بگیرید و بکشید(درگ اند دراپ برای با کلاس ها) و روی یک مقصد ول کنید.یک فلش ایجاد میشه که مشخصه یک action است. از یک مقصد چند action هم میتوانند سرچشمه بگیرند که بعدا با کد میگیم که کِی این اکشن ها اجرا شوند یا به عبارتی از یک مقصد به مقصد دیگر رویم.نگاهی به کد XML عکس بالا بیندازیم:دو فرگمنت داریم که مقصد های ما هستند. اون مقصدی که اکشن از ان سرچشمه گرفته(از اون مقصد به مقصد دیگر رفته ایم) یک تگ &lt;action&gt; دارد. یک id که وقتی بخواهیم بین این رو مقصد جا به جا شویم از ان استفاده میکنیم و یک  destination که مقصد را مشخص میکند.&lt;?xml version=&amp;quot1.0&amp;quot encoding=&amp;quotutf-8&amp;quot?&gt;
&lt;navigation xmlns:app=&amp;quothttp://schemas.android.com/apk/res-auto&amp;quot
    xmlns:tools=&amp;quothttp://schemas.android.com/tools&amp;quot
    xmlns:android=&amp;quothttp://schemas.android.com/apk/res/android&amp;quot
    app:startDestination=&amp;quot@id/blankFragment&amp;quot&gt;
    &lt;fragment
        android:id=&amp;quot@+id/blankFragment&amp;quot
        android:name=&amp;quotcom.example.cashdog.cashdog.BlankFragment&amp;quot
        android:label=&amp;quotfragment_blank&amp;quot
        tools:layout=&amp;quot@layout/fragment_blank&amp;quot &gt;
        &lt;action
            android:id=&amp;quot@+id/action_blankFragment_to_blankFragment2&amp;quot
            app:destination=&amp;quot@id/blankFragment2&amp;quot /&gt;
    &lt;/fragment&gt;
    &lt;fragment
        android:id=&amp;quot@+id/blankFragment2&amp;quot
        android:name=&amp;quotcom.example.cashdog.cashdog.BlankFragment2&amp;quot
        android:label=&amp;quotfragment_blank_fragment2&amp;quot
        tools:layout=&amp;quot@layout/fragment_blank_fragment2&amp;quot /&gt;
&lt;/navigation&gt;
جا به جایی بین مقصد ها:حالا وقت ان رسیده که بالاخره جا به جا شویم. NavController را یادتان هست؟ هر navHost یک NavController اختصاصی دارد که جا به جایی بین مقصد های ان navHost را کنترل میکند. برای اینکه جا به جا شویم به یک شی از ان نیاز داریم:اگر در کاتلین هستید اینطور یک شی از ان میگیریم(فرقی نمیکند از چه روشی):Fragment.findNavController()View.findNavController()Activity.findNavController(viewId: Int)و در جاوا:NavHostFragment.findNavController(Fragment)Navigation.findNavController(Activity, @IdRes int viewId)Navigation.findNavController(View)به کمک متد navigate میتوانیم به یک مقصد دیگر رویم.میتوانیم id مقصد را به عنوان پارامتر به ان دهیم یا به شیوه صحیح تر id اکشن را به ان دهیم.navControllerObject.navigate(action_id  or destination_id )جا به جایی اطلاعات بین مقصد ها:میدانید دیگه. مثلا یک EditText داریم که کاربر اسم خود را در ان وارد میکند و وقتی روی یک دکمه کلیک کرد میخواهیم اسم ان در یک فرگمنت دیگر نمایش داده شود. این دیتا(اسم کاربر) را باید با شی ‌Bundle جا به جا کنیم. طبیعتا به صورت زوج های کلید-مقدار. این ‌bundle را به عنوان پارامتر دوم متد navigate میدهیمBundle bundle = new Bundle();bundle.putString(&amp;quotname&amp;quot, user_name);navControllerObject.navigate(action_id  or destination_id , bundle)و در مقصد دریافت کننده با متد getArgument به ان bundle دسترسی خواهیم داشت:TextView name = findViewById(R.id.textViewName);
name.setText(getArguments().getString(&amp;quotname&amp;quot));فقط یک نکته مهم:باید در مقصد دریافت کننده دیتا بگیم که  قراره یک دیتایی برات ارسال بشه. از تب XML مقصدی که دیتا را دریافت میکند پیدا کنید و تگ &lt;action&gt; را به ان اضافه کنید:&lt;fragment android:id=&amp;quot@+id/myFragment&amp;quot &gt;
     &lt;argument
         android:name=&amp;quotmyArg&amp;quot
         app:argType=&amp;quotinteger&amp;quot
         android:defaultValue=&amp;quot0&amp;quot /&gt;
 &lt;/fragment&gt;این دیتا ورودی یک اسم دارد, نوع دارد که در app:argType مشخص شده و یک مقدار پیشفرض اختیاری دارد.راه پیشنهادی گوگل برای تبادل دیتا استفاده از پلاگین safe args است که در یک مقاله جداگانه به ان میپردازیم.برای اینکه مسلط تر بشید پیشنهاد میکنم داکیومنت ها navigation رو بخونید و یکم تمرین کنید. در قسمت بعد یکم مطالب پیشرفته تر میگیم و پلاگین safe args رو بررسی میکنیم و ...</description>
                <category>جامعه برنامه نویسان اندروید</category>
                <author>Mr. Robot</author>
                <pubDate>Wed, 06 May 2020 10:21:49 +0430</pubDate>
            </item>
                    <item>
                <title>پیاده سازی Theme در برنامه های اندرویدی</title>
                <link>https://virgool.io/AndroidPPub/theme-in-android-ifwzs7yym4xd</link>
                <description>سلام !! تو این مقاله میخوام باهم تم یا چند رنگی رو در برنامه های اندرویدی رو بررسی کنیم و اینکه Theme شب و روز (Light , Dark) رو پیاده سازی کنیم ، که با انجام اینکار پیاده سازی رنگ بندی های دیگ تفاوتی نداره و به سادگی قابل پیاده سازیه .البته من فقط بیس رو میگم و خروجی این نیست :)))خب ما در برنامه آیگپ از چندین تم و رنگ های مختلفی رو پشتیبانی میکنیم و دست کاربر در انتخاب رنگ و ظاهر برنامه بازه ، خیلی ها مثل من پرسپولیسی اند و تم قرمز رو انتخاب میکنن و خیلیا با حالت شب (Dark Theme) احساس بهتری حین استفاده از برنامه دارند و هر کسی طبق سلیقه خودش میتونه رنگ و تم مورد علاقه ش رو انتخاب کنه .برای پیاده سازی این مبحث اگر پروژه ای دارید که شروع نکردید کار سختی جز یسری کانفیگ ها ندارید و اگر هم پروژه طراحی شده و بزرگی دارید سخت ترین کارش تغییر لایه هاست و رنگ های ثابت رو به Attribute ها تغییر بدین که نسبت به تعداد لایه ها کار زمان بری میتونه باشه.از طرف دیگ پشتیانی Theme در اندروید زیر ۵ (Api 21) هم درد سر های خاص خودش رو داره که اگر حواستون نباشه باگ های زیادی رو متاسفانه برای طیف وسیعی از این کاربران :( بوجود میاره ...خب بعد از توضیح یکسری موارد بریم برای پیاده سازی Theme در برنامه هامون:برای اینکار بهتره ساختار برنامه تون از Single Activity پشتیبانی کنه ولی باز هم با همون ساختار اکتیویتی هم میتونید پیاده سازی کنید که نیاز به یسری کد های اضافه و مدیریت اون در  هر اکتیویتی داره.برای نگهداری وضعیت تم انتخابی کاربر میتونیم از Shared Preferences استفاده کنیم و وضعیت رو در اون ذخیره و بازیابی کنیم . https://gist.github.com/alirezanazari/5ee9a04153b2214a301c494c90c1efce همونطور که در کد بالا میبینید با استفاده از enum تم Dark و Light رو تعریف و در Shared Preferences با استفاده از متد ها ذخیره و بازیابی میکنم . در اولین متد یعنی getTheme یسری استایل با بررسی وضعیت تم انتخابی برگشت داده میشه که این Style رو در MainActivity و متد OnCreate و قبل از صدا زدن Super اون مقدار دهی میکنیم.  https://gist.github.com/alirezanazari/f37606361ec1b634f20ab72bb08bcd71 خب حالا این استایل ها چی اند ؟ ما تو اکثر پروژه ها یسری رنگ های ثابت داریم ; رنگ عنوان ها ، متون معمولی ، رنگ پس زمینه ، رنگ تولبار ، ساب تایتل ها ، دکمه ها و... که ما این رنگ ها رو بصورت Attribute تعریف و در لایه هامون به جای رنگ های ثابت استفاده میکنیم .برای اینکار فایل attrs.xml رو میسازیم و attribute ها و موارد ثابتی که بالا شمردیم رو تعریف میکنیم ، که فرمت هر attr میتونه color باشه که در TextColor , HintColor , Background و هرجایی که رنگ ثابت میدادیم و reference برای جاهایی که drawable , shape میگیرن مقدار دهی کنیم . https://gist.github.com/alirezanazari/9a6bf225b6bffac390cf44d9d504894c خب بعد از  این کار در فایل styles.xml با تعریف رنگ های Accent و Primary و همینطور فونت و.. یک فایل در پوشه res بنام themes.xml می سازیم که از BaseTheme تعریف شده ارث میبرن و رنگ هامون در هر تم رو مشخص میکنند. https://gist.github.com/alirezanazari/8e52d02aaac5d576199078d90f433a02 همونطور که تو کد های بالا میبینید تمام رنگ ها و Attribute های که در پروژه و نسبت به UI نیاز بود رو پیاده سازی کردیم .در کد بالا علاوه بر یسری رنگ ها Drawable هایی هم دیده میشه که ما میتونیم در لایه ها استفاده کنیم .خب میرسیم به استفاده از این مقادیر در لایه های برنامه مون که برای این کار به راحتی بجای رنگ و مقادیر ثابت با علامت ? و نام اون Attribute لایه مون رو رنگ بندی میکنیم.&lt;ImageView
    android:id=&amp;quot@+id/icSeen&amp;quot
    android:layout_width=&amp;quot@dimen/icons_size&amp;quot
    android:layout_height=&amp;quot@dimen/icons_size&amp;quot
    android:tint=&amp;quot?appTextTitleColor&amp;quot
    app:srcCompat=&amp;quot@drawable/ic_eye&amp;quot /&gt;

&lt;TextView
    android:layout_width=&amp;quotwrap_content&amp;quot
    android:layout_height=&amp;quotwrap_content&amp;quot
    android:textColor=&amp;quot?appTextTitleColor&amp;quot
    android:textSize=&amp;quot@dimen/medium_textSize&amp;quot
    tools:text=&amp;quotقسمت ۰۱&amp;quot /&gt;برای همه بخش ها به این صورت عمل میکنیم و رنگ ها رو با استفاده از attribute ها مقدار دهی میکنیم .همینطور Theme پیش فرض رو در بخش application در فایل manifests تغییر میدیم :android:theme=&quot;@style/LightTheme&quot;برای دیدن وضعیت رنگ ها در لایه مون نیازی نیست هر بار ران کنیم و در لایه XML و بخش Preview و قسمت بالا میتونیم بین Theme ها سوییچ کنیم .تمام کانفیگ ها انجام شد و حالا فقط سوییچ کردن بین تم ها مونده که بعضی برنامه ها برای انجام اینکار کارهای عجیبی مثل باز و بستن برنامه یا pop کردن تمام فرگمنت های اکتیویتی و شروع از نقطه اولیه و.. که هیچکدوم از این ها پیشنهاد نمیشه و تغییر تم باید بصورت smooth باشه و کاربر همون نقطه ای که سوییچ کرده از همون صفحه بتونه به کارش ادامه بده و مجبور به تکرار نباشه . برای تغییر تم همونطور که گفتم باید از پترن Single Activity استفاده کنیم و تمام فرگمنت های زیری رو  Attach/deAttach کنیم و اینکار هم نیاز نیست لیست تمام فرگمنت ها رو داشته باشیم و با attach/deattch کردن فرگمنت روت مون یا آیدی container مون بقیه صفحات آپدیت میشن .private fun updateViewForNewTheme(isDark: Boolean) {
    theme.setTheme(if (isDark) Theme.ThemeType.DARK else Theme.ThemeType.LIGHT)
    val fragment = activity?.supportFragmentManager?.findFragmentById(R.id.fragment_container)
    fragment?.let {
        activity?.supportFragmentManager?.beginTransaction()?.let {
            it.detach(fragment)
            it.attach(fragment)
            it.commit()
        }
    }
}برای اینکار بهتره یک فرگمنت روت داشته باشیم به عنوان  Main Fragment و بقیه صفحات رو تو اون اد کنیم و در خط اول onCreateView و قبل از super تم رو اپلای کنیم .context?.theme?.applyStyle(theme.getTheme(), true)خب بعد از ذخیره تم در Shared Preferences و تغییر اون یسری نکات ضروریه که گفته بشه:برای پشتیبانی Theme در دیوایس های زیر اندروید ۵ بایستی یک فایل values-21/themes.xml داشته  باشید که فایل تم که بالا ساختیم رو به این فایل انتقال بدیم و برای زیر ۵ از فایل values/themes.xml استفاده میکنیم که تنها تفاوتش در shape و drawable هایی که بصورت زیر تعریف شده :&lt;shape
    android:shape=&amp;quotrectangle&amp;quot
    xmlns:android=&amp;quothttp://schemas.android.com/apk/res/android&amp;quot&gt;

    &lt;solid
        android:color=&amp;quot?cardBackgroundColor&amp;quot/&gt;

    &lt;corners
        android:radius=&amp;quot@dimen/dp10&amp;quot/&gt;

&lt;/shape&gt;ست کردن رنگ ها در drawable ها و SVG ها باعث کرش در اندروید های زیر ۵ میشه و برای اینکار از دو فایل بالا استفاده میکنیم و در زیر ۵ از رنگ های ثابت برای هر تم استفاده میکنیم .مورد دوم که باید توجه کرد اینه که در inflate کردن لایه ها مخصوصا در فرگمنت و اداپتر ها برای پیروی لایه از Theme جاری برنامه از Context اکتیویتی بجای Application استفاده کنید چون تم در Main Acitivy ست شده و باید از کانتکست اون استفاده بشه :override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_profile_avatar , parent , false))
}و مورد سوم که شاید شما لایه ها و ویو هاتون رو بصورت کد جاوا یا کاتلین و بدون xml بنویسید که برای گرفتن تم و ست کردن رنگ ها از کد زیر میتونیم استفاده کنیم :private fun getColorFromAttr(context:Context , attrResId: Int): Int {
    val typedValue = TypedValue()
    val a = context.obtainStyledAttributes(typedValue.data, intArrayOf(attrResId))
    val color = a.getColor(0, 0)
    a.recycle()
    return color
}که حتما Context اکتیویتی و اون attribute که مدنظرتون رو بدید و رنگ دریافتی رو ست کنید.lastEnableTabTitle?.setTextColor(theme.getColorFromAttr(context ,R.attr.appTabDisableColor))خب این هم از پیاده سازی Theme در برنامه های اندرویدی که امیدوارم مفید بوده باشه براتون .وب سایت من </description>
                <category>جامعه برنامه نویسان اندروید</category>
                <author>علیرضا نظری</author>
                <pubDate>Fri, 24 Apr 2020 15:02:34 +0430</pubDate>
            </item>
                    <item>
                <title>چطور برنامه نویسی اندروید یاد بگیریم و پت و مت نشیم؟! راهنمایی برای مبتدی ها و بقیه</title>
                <link>https://virgool.io/AndroidPPub/%DA%86%D8%B7%D9%88%D8%B1-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%DB%8C%D9%85-%D9%88-%D9%BE%D8%AA-%D9%88-%D9%85%D8%AA-%D9%86%D8%B4%DB%8C%D9%85-qjoxejtmvsmz</link>
                <description>این مقاله حاصل یک سال از زندگی منه که سعی کردم اندروید یاد بگیرم. اشتباهات زیادی داشتم و بعضی مواقع مجبور شدم از صفر شروع کنم. شاید بعضی نکات یا منابع رو فراموش کرده باشم که به مرور اصلاح میکنم پس به این صفحه برگردید.اگر نکته یا منابعی سراغ دارید که من نگفتم هم خوشحال میشم بگید.یکسال از وقتی اندروید رو شروع کردم میگذره و احساس میکنم هنوز مبتدی هستم. دو تا دلیل اصلی داره：اندروید واقعا دنیای بزرگیه و هرچی توش سیر کنی هنوز چیز های هیجان انگیزی باقی موندهاشتباهاتی که اون اوایل داشتم خیلی من رو عقب انداخت. مثل پت و مت یک کاری میکردم و بعدا میزدم خرابش میکردم. شاید سه بار مجبور شدم از صفر شروع کنم. اخر مقاله میگم چرا.تو این مقاله هم کاری میکنم که بیشتر از اندروید لذت ببرید و هم اشتباهات من رو تکرار نکنید.یادگیری اندروید کار سختی نیست.دروغ گفتم ：) کار سختیه اما اگر از منابع درست استفاده کنید و حساب شده پیش برید و حسابی تمرین کنید این سختی میتونه تبدیل به لذت بشه. قدم اول： یک سفر کوتاه به کاتلینکاتلین در اصل اسم یک جزیره و البته زبان رسمی جدید گوگل برای برنامه نویسی اندروید هست. کاتلین نسبت به جاوا مزیت های زیادی داره و در کل حداقل با جاوا شروع نکنید. شاید یعدا نیاز به جاوا باشه ولی نه فعلا.اگر از قبل با جاوا اشنایی دارید که یادگیری کاتلین خیلی راحته. اگر هم نه با داکیومنت های خود سایت یا دوره های مختلف میتونید یاد بگیرید.من خودم با کتاب kotlin in action یاد گرفتم و فقط فصل اولشو خوندم و بقیه چیز هارو از سایت رسمی یاد گرفتم. چون خودم به اصطلاح خرکی یاد گرفتم نمیتونم دوره ای رو پیشنهاد کنم ولی دوره خوب زیاده نگران نباشید. تا مفاهیم شی گرایی یاد بگیرید و بقیه چیز هارو میشه در حین کار یاد گرفت.این قسمت بسته به سابقه و تلاش شما از یک هفته یا یک ماه وقت میگیره.قدم دوم： نصب اندروید استودیواندروید استودیو محیط رسمی برنامه اندروید است. البته با نصب پلاگین هایی روی intellij یا اکلیپس هم میتونید با اندروید کار کنید ولی انتخاب درستی نیست. بهینه ترین راه همین اندروید استودیو هست. نصبش هم اصلا سخت نیست(برعکس بعضی ها میگن سخت ترین بخش اش هست).کافیه برید به اینجا و با توجه به سیستم عامل تون اونو دانلود کنید.نزدیک یک گیگ حجم داره. یادتون باشه که به خاطر تحریم های نامردانه باید با تحریم شکن به این سایت برید. بعدا میگم چطور تحریم هارو دور بزنید.پکیج های مورد نیاز به صورت خودکار دانلود و نصب میشه اما ：قبل از باز کردن اندروید استودیو یه جوری تحریم ها رو دور بزنید. چه با VPN چه با شکن!شکن یه چیزیه(دقیق نمیدونم چیه) که باهاش راحت میتونید با تغییر دادن DNS تحریم ها رو دور بزنید. من با شکن نمیتونم تو یوتیوب برم ولی توی اندروید استودیو و سایت اندروید خوب کار میکنه. برید به سایت shecan.ir و طبق اموزش های خود سایت عمل کنید.قدم سوم ： انتخاب منابع مناسبسعی کنید یک منبع اصلی داشته باشید و طبق اون پیش برید. توی این بخش خیلی دقت کنید که ممکنه پت و مت بشید. از منابع فرعی هم به عنوان مکمل استفاده کنید.منابع اصلیدوره های سایت udacity.comدوره های اندروید این سایت یکی از بهترین منابع ویدیویی(هم با جاوا و هم با کاتلین) هستند که بعضی از اونها توسط گوگل تهیه شده و به شدت پیشنهاد میشه.کتاب android programming the big nerd ranch guide ویرایش چهارم این کتاب ارزشمند که کتاب مورد علاقه من هم هست با اختلاف بهترین کتاب اموزشی اندروید هست و با کاتلین اموزش میده. البته برای خوندن این کتاب خیلی زیاد به منابع فرعی نیاز پیدا میکنید که به نظرم یکی از مزیت هاش محسوب میشه.منابع فرعیسایت توسعه دهندگان اندرویدسایت developer.android.com داکیومنت های کاملی داره که هرچه حرفه ای تر میشید کاربرد این سایت هم براتون بیشتر میشه. معمولا بهترین و کامل ترین اموزش ها رو در این سایت پیدا میکنید.انجمن توسعه دهندگان اندروید در مدیومانجمن توسعه دهندگان اندروید در مدیوم مقاله های اموزشی خوبی منتشر میکنه. نویسنده های این مقاله ها برنامه نویس های گوگل هستند.انجمن های androidPub و mindOrks  در مدیوم هم انجمن های خوبی هستند که میتونید دنبال کنید.چطور از منابع استفاده کنیم؟پیشنهاد من اینه که یکی از منابع اصلی رو دنبال کنید چون ساختار منسجم تری دارند و هر وقت نیاز به اطلاعات بیشتر داشتید از منابع فرعی یا هرچیزی تو اینترنت بود استفاده کنید . ولی انسجام رو حفظ کنید.بعضی از منابع فرعی که معرفی کردم به قدری کامل هستند که نیازی بهش ندارید. فقط تا حدی بخونید که بتونید کتاب یا دوره اصلی رو دنبال کنید. و تمرین کنید و تمرین و تمرین. برنامه هایی که طبق اموزش ساختید رو کامل کنید و کم کم راه خودتون رو پیدا کنید.چطور تمرین کنیم؟بهترین راه اینه که یک پروژه شخصی برای خودتون تعریف کنید . چیزی تو مایه های notebook میتونه شروع خوبی باشه. در حین یادگیری پروژه رو کامل کنید و حتی یکم فراتر برید و یک چیز خلاقانه اضافه کنید.هر منبعی که دنبال میکنید کد های چیزی در حین اموزش درست کردید رو برای دانلود یا توی گیت هاب گذاشته. هر از چند وقت نگاهی به کد ها بندازید و سعی کنید بخونیدش . هم یاد اوری خوبیه و هم یاد میگیرید چطور کد بخونید.اگر سیستم ضعیفی دارید از لینوکس استفاده کنیدبرای اجرا درست اندروید استودیو به تنهایی به ۴ گیگ رم نیاز دارید. اگر بخواین چیز هایی مثل مرورگر و موزیک پلیر هم باز باشه به حداقل ۸ گیگ رم نیاز دارید. اگر سیستم ضعیفی دارید میتونید از لینوکس استفاده کنید. توزیع های سبکی مثل lubuntu وجود داره که به راحتی کار شما رو راه میندازه به علاوه از جذابیت های لینوکس هم بهره مند میشید.خود اندروید هم بر پایه لینوکس ساخته شده . پس یکم لینوکس در اینده به دردتون میخوره. به من اعتماد  کنید.از کجا کد های ساده پیدا کنیم؟هر وقت چیز جدیدی یاد گرفتید باید باهاش تمرین کنید و در یک پروژه واقعی استفاده کنید. اما اگر ذهنیتی ندارید که چی باید بسازید میتونید از کد ها و برنامه های ساده ای که با اهداف اموزشی نوشته شده رو بخونید.منبع اول اول سایت androidhive.com هست. توی این سایت تقریبا با همه کامپوننت ها و کتابخونه های اندروید میتونید یک پروژه ساده پیدا کنید و به همراه توضیحات بخونید.منبع دوم من کد های خود گوگل هست . این ریپوزیتوری مجموعه ای از برنامه های ساده است که توسط تیم اندروید گوگل تهیه شده . البته بگذارید یکم که سطح تون بالا تر رفت از این منابع استفاده کنید.چطور مثل پت و مت نشیم؟پت و مت رو که یادتون هست. اوایل کار های من شبیه این دو بزرگوار بود. میخواستم یه چیزی درست کنم ولی یه جای دیگه رو خراب میکردم. بیشتر هم برمیگشت به منابع نادرست و روش نادرست.هرچیزی که به نظر خوبه خوب نیستخیلی برام پیش اومده که یه کتابی رو شروع کنم و کلی بخونم ولی اخرش بفهمم کلا من رو به بیراهه برده در حالی که موقع خوندن کتاب حس میکردم خیلی باحاله! نمونه بارزش هم اموزش مقدماتی اندروید فرادرس هست. وقتی نگاه میکردم واقعا کیف میکردم که یه چیزی دارم میسازم... من دیگه خدای اندرویدم ... . بعد از اینکه کتابی رو که در بالا معرفی کردم رو شروع کردم دیدم اون مدرس عزیز فقط وقت من رو هدر میداده. فقط یک سری کامپوننت رو بی هدف اموزش میداده در حالی که در دنیای واقعی با مساعل جدی تری روبه رو هستیم. قصد بی احترامی به اون بزرگوار رو ندارم . اتفاقا من رو در شروع راه انداخت ولی...خلاصه اینکه هر منبعی که به نظرتون خوبه شاید زیرمیزی داره شما رو گمراه میکنه.بدون تمرین هیچی یاد نمیگیریماندروید پر از کلاس های شبیه به هم , مسیر های نسبتا بلند برای انجام دادن بعضی کار ها و البته مجموعه مفاهیمی هست که به هم وابسته هستند و لزوما درک اونها ساده نیست.پس باید کلی تمرین کنید ملکه ذهنتون بشه. اگر فقط یک کتاب خوندید و تمرین نکردید خودتون میبینید که هیچی یاد نگرفتید. اگر این دو اصل رو رعایت کنید هیچوقت کارتون به شروع از صفر نمیرسه</description>
                <category>جامعه برنامه نویسان اندروید</category>
                <author>Mr. Robot</author>
                <pubDate>Wed, 22 Apr 2020 20:11:51 +0430</pubDate>
            </item>
                    <item>
                <title>درک clean code در اندروید</title>
                <link>https://virgool.io/AndroidPPub/%D8%AF%D8%B1%DA%A9-clean-code-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-qszv5tm6y8hl</link>
                <description>قبل از شروع کدنویسی بهتر است بدانید چطور کد خود را مدیریت کنید و چطور کد خود را مقیاس پذیر کنیدهمون طور که عمو باب توی کتاب میگه(نویسنده کتاب مشهور clean code  معروف به عمو باب )：شما این مقاله رو به دو دلیل میخوانید：اول اینکه شما برنامه نویس هستید و دوم اینکه میخواهید برنامه نویس بهتری بشید.(Robert C. Martin  )همونطور که ایشون میگه تصور کنید توی کتابخانه ای هستید و دارید به چند تا کتاب نگاه میکنید. اگر کتابخانه کتاب هاش رو مدیریت و دسته بندی کرده باشه شما سریعتر کتاب مورد نظرتون رو پیدا میکنید. به علاوه طراحی داخلی خوب باعث میشه وقتی دنبال کتاب میگردید احساس راحتی کنید.مثل نوشتن کتاب, اگر میخواهید چیز فوق العاده ای بسازید باید بدونید چطور بنویسید و چطور کدتون رو تر و تمیز سازماندهی کنید. اگه تیم دارید یا کسی غیر از شما کدتون رو میبینه کافیه به اسم متغیر ها و کلاس ها و پکیج ها نگاه کنه تا برنامه رو درک کنه.کد تمیز چیست؟اینکه کارتون رو سریعتر تموم کنید ولی کسی نتونه کد شما رو بخونه اصلا خوب نیست چون خودش یه بدهی فنی محسوب میشه.کد شما تمیز محسوب میشه اگه هرکسی در تیم شما بتونه راحت درکش کنه. کد تمیز میتونه توسط بقیه توسعه دهنده ها خوانده و توسعه داده بشه. با قابل فهم بودن, خوانایی, تغییرپذیری, توسعه پذیری و قابلیت نگهداری هم میاد.-- باید بهش اهمیت بدم؟دلیل اینکه باید بهش اهمیت بدید اینه که کد شما , خط فکری شما رو به دیگران توضیح میده.این دلیلیه که به خاطرش باید به افزایش خوانایی, زیبایی و سادگی کدتون فکر کنید.مشخصات کد تمیز：اگر کد شما مشخصات زیر را داشت بدانید و اگاه باشید که تمیز است.کد شما زیبا است： کد شما باید مثل گوش دادن به اهنگ های محسن چاوشی یا یه ماشین خوش ساخت شما رو وادار به لبخند زدن کنه.کد شما مورد مراقبت قرار گرفته باشد：وقت صرف کنید که کدتون رو ساده و متظم نگه دارید. به جزییات اهمیت دهید و از ان نگهداری کنید.کد شما متمرکز و هدفمند است：هر تابع، هر کلاس و هر ماژول باید از یک خط فکری مشخص پیروی کند که با جزییات پیرامون ان , غیر قابل فهم و کثیف نشده باشد.از تکرار کد پرهیز کرده باشد.همه تست ها را پاس کند.تعداد تابع ها و کلاس ها در آن به حداقل رسیده باشد.یک فرق برنامه نویس باهوش و برنامه نویس حرفه این است که, حرفه ای میداند تمیزی و نظم حرف اول را میزند.حرفه ای ها از قدرتشان خوب استفاده میکنند و کدی مینویسند که دیگران هم آنرا بفهمند.از اسم های با معنا استفاده کنید：انتخاب اسم خوب زمان میبرد ولی بیشتر از چیزی که میگیرد , برمیگرداند. اسم متغیر ها و تابع ها و کلاس ها باید به همه سوالات بزرگ جواب دهد.باید بگوید چرا وجود دارد, چه کاری انجام میدهد و چطور استفاده میشود.اگر اسمی نیاز به کامنت و توضیح داشت نیت خود را به خوبی مشخص نمیکند.بیایید چند مثال ببینیم.--اسم کلاس هاکلاس ها و اشیا (objects) باید اسم یا اسم-عباراتی(اسمی که از چند کلمه تشکیل شده) مثل Customer, WikiPage, Account, و AddressParser داشته باشند. از کلماتی مثل Manager, Processor, Data, یا Info در اسم کلاس استفاده نکنید. اسم کلاس نباید فعل باشد.--اسم تابع هااسم تابع ها باید فعل باشد مثل：postPayment, deletePage, یا  save.  و Accessors, mutators, و predicates(مثل getter ها و setter ها) باید بر اساس مقدارشون نامگذاری شوند  و پیشوند های get و set و هرچیزی مطابق استاندارد javabean داشته باشند.— Use Problem Domain NamesWhen there is no “programmer-eese” for what you’re doing, use the name from the problem domain. At least the programmer who maintains your code can ask a domain expert what it means.(اینو خودم نفهمیدم ولی گذاشتم که بهم توضیح بدید)کدتون رو بر اساس اصول S.O.L.I.D بنویسید.این اصل توسط خود Robert C. Martin (عمو باب) ساخته شده. SOLIC مجموعه اصولی است که کد خوب رو توصیف میکنه.اصل Single Responsibility --اصل تک وظیفگی (SRP)  ：یعنی هر کلاس باید فقط یک مسعولیت داشته باشه. هرگز یک کلاس نباید بیش از یک دلیل برای به وجود اومدن داشته باشه.فقط چون میتونی هر چی دلت خواست به کلاس اضافه کنی به این معنی نیست که باید اینکارو انجام بدی. کلاس های بزرگ رو به کلاس های کوچک تر تقسیم کن و از GOD کلاس ها دوری کن.به عنوان مثال：فرض کنید  یک RecyclerView.Adapter داریم که بخشی از منطق برنامه(حالا هر چیزی به غیر از Bind کردن اطلاعات) رو توی onBindViewHolder مشخص شده.این باعث میشه که RecyclerView.Adapter  بیشتر از یک مسعولیت داشته باشه. این تابع فقط مسعول اینه که اطلاعات جدید رو بده به view و اونا رو bind کنه.اصل Open-Closed -- اصل باز و بسته بودن (OCP) :اجزا نرم افزار(کلاس,متد) باید برای گسترش ازاد و برای تغییر محدود باشه. یعنی مثلا اگر کلاسی به اسم A داشته باشیم و هم تیمی شما بخواد توی یکی از تابع های توی A تغییری ایجاد کنه میتونه با extend کردن Aاینکارو انجام بده به جای اینکه تو کلاس اصلی تغییر ایجاد کنه.یک مثال ساده همین کلاس RecyclerView.Adapter است. خیلی راحت میتونید با ارث بری کردن(extend) , آداپتر مخصوص خودتون با رفتار دلخواه بسازید بدون اینکه نیاز به تغییر RecyclerView.Adapter داشته باشید.اصل Liskov Substitutions -- اصل جانشینی لیسکف (LSP):کلاس فرزند(child classes) هیچوقت نباید از تعریف کلاس پدر(parent class) سرپیچی کند.(یا یه همچین چیزی)یعنی زیرکلاس باید متد هایی از کلاس پدر رو override کنه که از توانایی های کلاس پدر فراتر نره. برای مثال, یک interface داریم که متد () داره. بعد از  توی MyActivity استفاده میکنیم به طوری که یک toast نمایش میدهد.
interface ClickListener {
    fun ()
}
class MyActivity: AppCompatActivity(), ClickListener {

    //........
    override fun () {
        // Do the magic here
        toast(&amp;quotOK button clicked&amp;quot)
    }
}***میدونم یکم پیچیده شد. یکم تو اینترنت براش وقت بگذارید.اصل Interface Segregation：این اصل بیان میکند که امکانات و متد هایی که به مشتری(client) مربوط نیست و از انها استفاده نمیکند , نباید به مشتری تحمیل کرد.یعنی اگر بخواهید کلاس A  را بسازید و اون رو توی یه کلاس دیگه implement کنید( کلاس B), نباید همه متد های A رو توی کلاس override , B بشه. برای اینکه اونو تر و تمیز در بیاریم.مثال: توی اکتیویتون نیاز به implement کردن SearchView.OnQueryTextListener() دارید و فقط به متد onQuerySubmit نیاز دارید. فقط لازمه یه callback بسازید و کلاسی که از SearchView.OnQueryTextListener() ارث بری میکند.اصل Dependency Inversion :به انتزاعات بستگی داره. به ارتباطات بستگی ندارهعمو باب میگه این اصل از دو بخش تشکیل شده:متد های High-level نباید به متد های low-level بستگی داشته باشد. هر دو باید به انتزاعات وابسته باشند.انتزاعات نباید به جزییات وابسته باشند. جزییات باید به انتزاعات بستگی داشته باشد.متد های high-level که منطق پیچیده ای را به دوش میکشند باید قابلیت باز استفاده داشته باشند و از متد های low-level  تاثیر نپذیرند. برای انجام اون باید ابتدا انتزاعی ایجاد کنید که متد های high-level و low-level  رو از هم جدا کنه.منبع: Medium </description>
                <category>جامعه برنامه نویسان اندروید</category>
                <author>Noah</author>
                <pubDate>Wed, 18 Mar 2020 21:40:12 +0330</pubDate>
            </item>
            </channel>
</rss>