آموزش معماری MVVM در اندروید (قسمت دوم)

MVVM
MVVM


در قسمت قبل توانستیم درکی از MVVM و LiveData بدست آوریم و همچنین کتابخانه های مورد نیاز پروژه را اضافه کردیم. همانطور که گفته شد، پروژه یک اپلیکیشن ساده است که لیستی از آلبوم ها را از سرور دریافت میکند و با استفاده از RecyclerView به کاربر نمایش می‌دهد. همچنین با کلیک بر روی یک آلبوم به صفحه آن آلبوم رفته و لیست آهنگ های آلبوم را نمایش می‌دهد.

برای جلوگیری از طولانی شدن مطلب به جای قرار دادن بعضی از کد ها که نیاز خاصی به توضیح ندارند (مانند کد صفحه های xml برنامه) لینک کدهای صفحه مربوطه رو در گیت‌هاب خودم قرار دادم تا قابل استفاده باشد.

در اولین قدم به سراغ پیاده سازی رابط کاربری برنامه می‌رویم. در این برنامه من از Fragment استفاده میکنم. بنابراین در صفحه activity_main.xml یک TabLayout و ViewPager تعریف میکنم.

در قدم بعد در فایل xml فرگمنتی که ایجاد کردم یک RecyclerView قرار میدهم. کد صفحه fragment_home.xml به صورت زیر است:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="168dp"
    xmlns:tools="http://schemas.android.com/tools"
    >

    <androidx.recyclerview.widget.RecyclerView
        android:[email protected]+id/recycler_xml"
        android:layout_width="match_parent"
        android:layout_height="168dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        tools:[email protected]/albums_item"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

بعد از ساخت صفحه 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("Albums"));
        tabLayout.addTab(tabLayout.newTab().setText("Playlists"));
        tabLayout.addTab(tabLayout.newTab().setText("Reviews"));
        tabLayout.addTab(tabLayout.newTab().setText("Songs"));

        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("album.php")
    Call<List<AlbumModel>> getAlbum();

    @GET("music.php")
    Call<List<SongModel>> getMusic();
}

همچنین یک کلاس برای کانفیگ رتروفیت می‌نویسیم:

public class RetrofitBuilder
{
    private final String baseUrl = "http://your_web_site.com"

    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