<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Farid</title>
        <link>https://virgool.io/feed/@far7id</link>
        <description>توسعه دهنده، مهندس نرم افزار</description>
        <language>fa</language>
        <pubDate>2026-06-16 14:06:07</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/26461/avatar/lfZfgd.jpg?height=120&amp;width=120</url>
            <title>Farid</title>
            <link>https://virgool.io/@far7id</link>
        </image>

                    <item>
                <title>آموزش معماری MVVM در اندروید (قسمت سوم)</title>
                <link>https://virgool.io/@far7id/mvvm-architecture-part3-tvd1wgkzve5a</link>
                <description>ViewModelدر قسمت قبل بخش های Model و View را نوشتیم و طراحی کردیم. همچنین کلاسی برای بیلدر رتروفیت و اینترفیسی برای درخواست های Http نوشتیم. در این بخش به سراغ مهم ترین قسمت این دوره، یعنی ViewModel خواهیم رفت.همانطور که در قسمت اول گفته شد، ViewModel ارتباط بین Model و View را برقرار می‌کند. ViewModel به وسیله LiveData رابط کاربری را بروز نگه می‌دارد.در مرحله اول یک کلاس تحت عنوان RetrofitMusicViewModel ایجاد میکنیم که از کلاس androidx.lifecycle.ViewModel ارث بری میکند. همچنین یک MutableLiveData تعریف میکنم که لیستی از نوع AlbumMode است. private MutableLiveData&lt;List&lt;AlbumModel&gt;&gt; albumListLiveData;در مهم ترین قسمت این کلاس یک تابع از نوع void به نام loadList مینویسیم.private void loadList()
{
    RetrofitBuilder retrofitBuilder = new RetrofitBuilder();
    Call&lt;List&lt;AlbumModel&gt;&gt; call = retrofitBuilder.retrofitConfig().getAlbum();

    call.enqueue(new Callback&lt;List&lt;AlbumModel&gt;&gt;()
    {
        @Override
        public void onResponse(Call&lt;List&lt;AlbumModel&gt;&gt; call, Response&lt;List&lt;AlbumModel&gt;&gt; response)
        {
            if (!response.isSuccessful())
            {
                Log.e(&amp;quotCode: &amp;quot, String.valueOf(response.code()));
                return;
            }

            albumListLiveData.setValue(response.body());
            Log.e(&amp;quotonResponse&amp;quot, response.body().toString());
        }

        @Override
        public void onFailure(Call&lt;List&lt;AlbumModel&gt;&gt; call, Throwable t)
        {
            Log.e(&amp;quotonFailure&amp;quot, t.getMessage());
        }
    });
}در این تابع برای استفاده از رتروفیت یک شی از کلاس RetrofitBuilder که قبلا ایجاد کرده بودیم تعریف و سپس از متد retrofitConfig استفاده کرده و درخواست getAlbum که قبلا در اینترفیس Api نوشته بودیم را در call میریزیم.سپس درخواست call را برای اجرا کردن نوشته و در onResponse لیستی را که سرور برگردانده بود را در  albumListLiveData قرار می‌دهیم. حالا ما یک متد داریم که درخواست رتروفیت را اجرا میکند و داخل لیستی که تعریف کرده ایم قرار می‌دهد. همچنین به یک متد دیگر برای برگرداندن لیستی که پر شده نیاز داریم. بنابراین آن تابع را به این صورت تعریف میکنیم:public LiveData&lt;List&lt;AlbumModel&gt;&gt; getAlbum()
{
    if (albumListLiveData == null)
    {
        albumListLiveData = new MutableLiveData&lt;List&lt;AlbumModel&gt;&gt;();
        loadList();
    }

    return albumListLiveData;
}یک تابع به نام getAlbum که لیستی LiveData از نوع AlbumModel را برمیگرداند. اگر لیست خالی باشد تابع  loadList را فراخوانی میکند و در غیر این صورت لیست را برمیگرداند.در آخرین مرحله برای اینکه اطلاعات را بگیریم و در RecyclerView نمایش دهیم به نوشتن این تکه کد در کلاس HomeFragment نیاز است:RetrofitMusicViewModel rmvm = ViewModelProviders.of(getActivity()).get(RetrofitMusicViewModel.class);

rmvm.getAlbum().observe(getActivity(), new Observer&lt;List&lt;AlbumModel&gt;&gt;()
{
    @Override
    public void d(List&lt;AlbumModel&gt; musicModels)
    {
        recyclerAlbumAdapter = new RecyclerAlbumAdapter(musicModels, getActivity());
        recyclerView.setAdapter(recyclerAlbumAdapter);
    }
});در این خطوط یک شی از کلاس RetrofitMusicViewModel ایجاد کردیم که با استفاده از ViewModelProviders که یک context دریافت میکند که از متد getActivity استفاده میکنیم (به دلیل اینکه کلاس فرگمنت است و نه اکتیویتی)، و در آخر کلاس RetrofitMusicViewModel را get کرده و در شی rmvm قرار می‌دهیم.سپس از شی rmvm استفاده کرده و متد getAlbum که در کلاس ViewModel نوشته بودیم که لیست دریافت شده از سرور را برمیگرداند را صدا زده و observe می‌کنیم. با تایپ کلمه new و بعد از آن O، اندروید استودیو به شما متد را پیشنهاد میدهد و با زدن اینتر آن را کامل میکند. با زدن اینتر متدی به اسم  نوشته می‌شود. با استفاده از این متد هنگامی که تغییری روی داده ما (لیست musicModels) صورت بگیرد ما مطلع می‌شویم. در نهایت داخل این متد شی recyclerAlbumAdapter را new کرده و لیستی که observable به ما داده است را به آداپتر ریسایکلر ویو می‌دهیم. و در نهایت آداپتر را ست میکنیم.در نهایت صفحه ما به این صورت است:MainActivity (HomeFragment)در این صفحه در فرگمنت اول لیستی از پست ها گرفتیم که عکس های آن ها را با استفاده از کتابخانه Glide دانلود و در ریسایکلر ویو نمایش دادیم.همانطور که گفته شده بود با کلیک بر روی البوم باید لیست آهنگ های آلبوم در صفحه دیگری ظاهر شود. به همین جهت یک کلاس جاوا و فایل xml دیگری میسازیم. کد های فایل activity_album.xml:https://github.com/far7id/Mvvm/blob/master/app/src/main/res/layout/activity_album.xmlهمچنین یک آداپتر برای ریسایکلر ویو این صفحه مینویسیم و در متد onBindViewHolder آن این تکه کد را مینویسیم:musicModel = musicList.get(position);

View view = layoutInflater.inflate(R.layout.albums_item, null, false);

Glide.with(view.getContext())
        .load(musicList.get(position).getPic())
        .into(pic);

recyclerHolder.itemView.setListener(new View.Listener()
{
    @Override
    public void (View v)
    {
        Intent intent = new Intent(context, AlbumActivity.class);

        String titlePosition = musicModel.getTitle();
        String artistPosition = musicModel.getArtist();
        String picPosition = musicList.get(position).getPic();

        intent.putExtra(&amp;quottitlePosition&amp;quot, titlePosition);
        intent.putExtra(&amp;quotartistPosition&amp;quot, artistPosition);
        intent.putExtra(&amp;quotpicPosition&amp;quot, picPosition);

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
});این کلاس مانند آداپتر قبلی است با این تفاوت که در این متد یک رویداد  هم نوشته‌ایم. بنابراین با کلیک بر روی یک آلبوم فیلد های آن گرفته می‌شود و به وسیله putExtra به اکتیویتی AlbumActivity ارسال می‌شود.سپس در کلاس اکتیویتی AlbumActivity که ایجاد کرده بودیم به وسیله Bundle اطلاعات را دریافت می‌کنیم و روی ویو های مربوطه ست می‌کنیم.در نهایت مانند فرگمنت اصلی که طراحی کرده بودیم از ViewModel استفاده و آن‌ را observe می‌کنیم.RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(AlbumActivity.this);
recyclerView.setLayoutManager(layoutManager);

RetrofitMusicViewModel rmvm = ViewModelProviders.of(AlbumActivity.this).get(RetrofitMusicViewModel.class);

rmvm.getSong().observe(AlbumActivity.this, new Observer&lt;List&lt;SongModel&gt;&gt;()
{
    @Override
    public void d(List&lt;SongModel&gt; songModels)
    {
        recyclerSongAdapter = new RecyclerSongAdapter(songModels, AlbumActivity.this);
        recyclerView.setAdapter(recyclerSongAdapter);
    }
});کد های اکتیویتی AlbumActivity:https://github.com/far7id/Mvvm/blob/master/app/src/main/java/com/example/MvvmDagger/view/ui/Activity/AlbumActivity.javaدر نهایت صفحه AlbumActivity به صورت زیر است:AlbumActivityدر این پروژه یک نمونه ساده و کاربردی از کار با MVVM تجربه کردیم. همچنین با کامپوننت LiveData آشنا شدیم از آن در یک پروژه استفاده کردیم. هدف از این پروژه آشنایی و درک بیشتر معماری MVVM بود. در نظر داشته باشید که این فقط یک نمونه ساده از پیاده سازی این معماری می‌باشد و مطمئننا MVVM مباحث بسیار دیگری دارد که با تحقیق و جستجو در اینترنت و تمرین می‌توانید از آن ها استفاده کنید. لینک کد های کامل این پروژه در صفحه گیت‌هاب من قرار دارد و شما می‌توانید به طور کامل از کد های این پروژه استفاده کنید.https://github.com/far7id/Mvvmممنون از وقتی که برای این دوره گذاشتید. امیدوارم این دوره برای شما مفید بوده باشد :)</description>
                <category>Farid</category>
                <author>Farid</author>
                <pubDate>Thu, 26 Mar 2020 20:19:53 +0430</pubDate>
            </item>
                    <item>
                <title>آموزش معماری MVVM در اندروید (قسمت دوم)</title>
                <link>https://virgool.io/@far7id/mvvm-architecture-part2-qzecvfd34ptk</link>
                <description>MVVMدر قسمت قبل توانستیم درکی از MVVM و LiveData بدست آوریم و همچنین کتابخانه های مورد نیاز پروژه را اضافه کردیم. همانطور که گفته شد، پروژه یک اپلیکیشن ساده است که لیستی از آلبوم ها را از سرور دریافت میکند و با استفاده از RecyclerView به کاربر نمایش می‌دهد. همچنین با کلیک بر روی یک  آلبوم به صفحه آن آلبوم رفته و لیست آهنگ های آلبوم را نمایش می‌دهد.برای جلوگیری از طولانی شدن مطلب به جای قرار دادن بعضی از کد ها که نیاز خاصی به توضیح ندارند (مانند کد صفحه های xml برنامه) لینک کدهای صفحه مربوطه رو در گیت‌هاب خودم قرار دادم تا قابل استفاده باشد.در اولین قدم به سراغ پیاده سازی رابط کاربری برنامه می‌رویم. در این برنامه من از Fragment استفاده میکنم. بنابراین در صفحه activity_main.xml یک TabLayout و ViewPager تعریف میکنم.در قدم بعد در فایل xml فرگمنتی که ایجاد کردم یک RecyclerView قرار میدهم. کد صفحه fragment_home.xml به صورت زیر است:&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
    android:layout_width=&amp;quotmatch_parent&amp;quot
    android:layout_height=&amp;quot168dp&amp;quot
    xmlns:tools=&amp;quothttp://schemas.android.com/tools&amp;quot
    &gt;

    &lt;androidx.recyclerview.widget.RecyclerView
        android:id=&amp;quot@+id/recycler_xml&amp;quot
        android:layout_width=&amp;quotmatch_parent&amp;quot
        android:layout_height=&amp;quot168dp&amp;quot
        app:layout_constraintTop_toTopOf=&amp;quotparent&amp;quot
        app:layout_constraintLeft_toLeftOf=&amp;quotparent&amp;quot
        android:paddingLeft=&amp;quot16dp&amp;quot
        android:paddingRight=&amp;quot16dp&amp;quot
        tools:listitem=&amp;quot@layout/albums_item&amp;quot
        /&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;بعد از ساخت صفحه xml اکتیویتی main به سراغ نوشتن کد جاوا MainActivity می‌رویم.public class MainActivity extends AppCompatActivity
{
    private ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TabLayout tabLayout = findViewById(R.id.tab_xml);
        viewPager = findViewById(R.id.view_pager_xml);

        tabLayout.addTab(tabLayout.newTab().setText(&amp;quotAlbums&amp;quot));
        tabLayout.addTab(tabLayout.newTab().setText(&amp;quotPlaylists&amp;quot));
        tabLayout.addTab(tabLayout.newTab().setText(&amp;quotReviews&amp;quot));
        tabLayout.addTab(tabLayout.newTab().setText(&amp;quotSongs&amp;quot));

        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        final PagerAdapter adapter = new PagerAdapter(this,getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(adapter);

        viewPager.addChangeListener(new TabLayout.TabLayoutChangeListener(tabLayout));

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
        {
            @Override
            public void onTabSelected(TabLayout.Tab tab)
            {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab)
            {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab)
            {

            }
        });
    }

}در این صفحه کار خاصی صورت نگرفته، یک ViewPager تعریف کردیم و یک TabLayout که چهار تب یا به مقدار دلخواه برایش در نظر گرفته ایم. به کلیک بر روی هر تب، فرگمنت مربوط به آن تب باز می‌شود و می‌توانیم بین فرگمنت های تعریف شده سوییچ کنیم.برای کار کردن TabLayout باید یک کلاس دیگر تحت عنوان PagerAdapter بسازیم که تعداد تب ها و کلاس مربوط به هر تب را مشخص میکند که در MainActivity از این آداپتر استفاده کرده‌ایم.کد های کلاس PagerAdapter:https://github.com/far7id/Mvvm/blob/master/app/src/main/java/com/example/MvvmDagger/view/adapter/PagerAdapter.javaیک فایل جاوای دیگر برای فرگمنت اصلی تحت عنوان HomeFragment ساخته که از کلاس Fragment ارث بری میکند و کد های زیر را در آن مینویسیم:public class HomeFragment extends Fragment
{
    private RecyclerView recyclerView;
    private RecyclerAlbumAdapter recyclerAlbumAdapter;

    public HomeFragment()
    {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        recyclerView = view.findViewById(R.id.recycler_xml);

        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
        recyclerView.setLayoutManager(layoutManager);

        return view;
    }
}همچنین کلاس آداپتر RecyclerAlbumAdapter به این صورت است:https://github.com/far7id/Mvvm/blob/master/app/src/main/java/com/example/MvvmDagger/view/adapter/RecyclerAlbumAdapter.javaبا فرستادن درخواست GET به سرور من یک لیست به صورت Json دریافت می‌کنم که شامل چهار فیلد id, title, artist,pic است که در دیتابیس بر روی سرور ذخیره شده اند. بنابراین یک کلاس برای قسمت Model پروژه ام ایجاد میکنم تحت عنوان AlbumModel که یک کلاس مدل ساده شامل فیلد های گفته شده، یک متد سازنده و Getter و Setter می‌باشد.کلاس AlbumModel:https://github.com/far7id/Mvvm/blob/master/app/src/main/java/com/example/MvvmDagger/service/model/AlbumModel.javaوقت استفاده از Retrofit است. برای استفاده از رتروفیت یک اینترفیس به نام Api به صورت زیر ایجاد می‌کنم که شامل دو درخواست از نوع GET است که اولی لیستی از نوع AlbumModel و دومی لیستی از نوع SongModel است:public interface Api
{
    @GET(&amp;quotalbum.php&amp;quot)
    Call&lt;List&lt;AlbumModel&gt;&gt; getAlbum();

    @GET(&amp;quotmusic.php&amp;quot)
    Call&lt;List&lt;SongModel&gt;&gt; getMusic();
}همچنین یک کلاس برای کانفیگ رتروفیت می‌نویسیم:public class RetrofitBuilder
{
    private final String baseUrl = &amp;quothttp://your_web_site.com&amp;quot

    public Api retrofitConfig()
    {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        Api api = retrofit.create(Api.class);

        return api;
    }
}این کلاس Builder رتروفیت است که شامل یک متد به نام retrofitConfig است که یک شی api برمیگرداند. فرض بر این است که شما تجربه استفاده از کتابخانه Retrofit را دارید، به همین علت روی توضیح دادن جزئی ‌کد های Retrofit تمرکز نمی‌کنیم و به همین توضیحات کلی اکتفا می‌کنیم.تا اینجا بخش Model که شامل کلاس AlbumModel و بخش View که شامل کلاس های اکتیویتی و آداپتر ها می‌شود را طراحی کردیم. در قسمت بعد به مهم ترین بخش دوره یعنی ViewModel می‌رویم تا اتصال بین دیتا ها و رابط کاربری برنامه را برقرار کنیم :)لینک قسمت سوم:https://virgool.io/@far7id/mvvm-architecture-part3-tvd1wgkzve5a</description>
                <category>Farid</category>
                <author>Farid</author>
                <pubDate>Thu, 26 Mar 2020 00:40:00 +0430</pubDate>
            </item>
                    <item>
                <title>آموزش معماری MVVM در اندروید (قسمت اول)</title>
                <link>https://virgool.io/@far7id/mvvm-architecture-part1-hveifzlygelb</link>
                <description>در کنفرانس Google I/O در سال 2017، گوگل کامپوننت هایی را که شامل LiveData و ViewModel بودند رو به همراه معماری MVVM معرفی کرد.در این دوره قصد دارم معماری MVVM را معرفی و در یک پروژه ساده پیاده سازی کنم.اما MVVM چی هست؟در برنامه نویسی برای نوشتن پروژه های نسبتا بزرگ مانند یک اپلیکیشن کامل برای بهینگی و نگه داری ساده تر کد ها از معماری های مختلف مانند MVC استفاده می‌شود. یکی از این معماری ها که تقریبا دنیای اندروید را به سمت خود می‌کشد MVVM هست.معماری MVVM منطق برنامه و رابط کاربری برنامه را از هم جدا میکند و باعث می‌شود مدیریت برنامه ساده تر و خوانایی کد ها بیشتر شود. معماری MVVM در اندروید به وسیله دو کامپوننت که LiveData و ViewModel پیاده سازی می‌شود.این معماری از سه لایه تشکیل شده است:۱- Modelلایه Model شامل کلاس هایی که داده ها در اونها قرار میگیرند، مانند کلاس دانشجویان، کاربران و ...۲- Viewلایه ای که اصطلاحا UI برنامه یا رابط کاربری برنامه را تشکیل میدهد که شامل کلاس های اکتیویتی ها و Adapter هاست.۳- ViewModelاین لایه مهمترین لایه این معماری محسوب می‌شود که ارتباط بین دو لایه View و Model را با هم برقرار میکند. ViewModel به این صورت عمل میکند که با لایه Model ارتباط دارد و وظیفه آماده سازی observable  (در انگلیسی به معنای قابل مشاهده) ها را برای observed شدن (مشاهده شدن) توسط لایه View دارد.شکل زیر به درک بهتر این معماری کمک می‌کند.معماری MVVMهمانطور که گفته شد، این معماری در اندروید با کامپوننت LiveData استفاده می‌شود.اما LiveData چیست؟یک کامپوننت معماری تازه معرفی شده است. LiveData یک نگهدارنده داده observable است. LiveData تغییرات را رصد میکند و تاثیر این تغییرات را بر View ها اعمال میکند. در واقع LiveData پل ارتباطی میان View و ViewModel است. برای مثال یک اکتیویتی را تصور کنید که از سرور لیست کاربران را دریافت و نمایش می‌دهد. در کلاس‌مان یک لیست به عنوان LiveData داریم که به عنوان Observable عمل می‌کند و در اکتیویتی اصلی این لیست را Observe میکنیم و نمایش می‌دهیم.و اما شروع کار با MVVMبرای درک بهتر MVVM یک پروژه ساده می‌سازیم که لیستی از آلبوم ها را از سرور دریافت میکند و با استفاده از RecyclerView به کاربر نمایش می‌دهد. همچنین با کلیک بر روی یک آلبوم به صفحه آن آلبوم رفته و لیست آهنگ های آلبوم را نمایش می‌دهد.یک پروژه جدید در اندروید استودیو ایجاد کنید. وارد فایل build.gradle برنامه شوید و کتابخانه های مورد استفاده را به پروژه اضافه کنید.//Ui
implementation &#039;com.google.android.material:material:1.1.0&#039;
implementation &#039;androidx.recyclerview:recyclerview:1.1.0&#039;
implementation &#039;com.makeramen:roundedimageview:2.3.0&#039;

//Network
implementation &#039;com.google.code.gson:gson:2.8.5&#039;
implementation &#039;com.squareup.retrofit2:retrofit:2.6.2&#039;
implementation &#039;com.squareup.retrofit2:converter-gson:2.6.2&#039;
implementation &#039;com.squareup.okhttp3:okhttp:4.2.0&#039;
implementation &#039;com.github.bumptech.glide:glide:4.7.1&#039;

//Mvvm
implementation &#039;androidx.lifecycle:lifecycle-viewmodel:2.3.0-alpha01&#039;`
implementation &#039;androidx.lifecycle:lifecycle-extensions:2.2.0&#039;
annotationProcessor &#039;androidx.lifecycle:lifecycle-compiler:2.3.0-alpha01&#039;برای گذراندن این آموزش حتما باید تجربه کار با کتابخانه های Retrofit و Okhttp داشته باشید و مبحث ارتباط با اینترنت از طریق این کتابخانه ها را بلد باشید، در غیر این صورت این دوره برای شما زود هنگام هست.در قسمت بعد کد نویسی پروژه را شروع میکنیم :)لینک قسمت دوم:https://virgool.io/@far7id/mvvm-architecture-part2-qzecvfd34ptk</description>
                <category>Farid</category>
                <author>Farid</author>
                <pubDate>Tue, 24 Mar 2020 14:08:51 +0430</pubDate>
            </item>
            </channel>
</rss>