مقالات باگتو

برقراری ارتباط بین Fragment و Activity با استفاده از ViewModel
برقراری ارتباط بین Fragment و Activity با استفاده از ViewModel

در ماه های اول که تازه برنامه نویسی رو یاد گرفته بودم نمایش لایو داده ها برایم کار بسیار دشوار و پیچیده ای بود و خیلی کدهای گیج کننده ای می نوشتم اما با مطالعه چندین مقاله یاد گرفتم که با استفاده از فرگمت این کار رو خیلی راحت و بدون دردسر میتوانم انجام بدهم و میخوام استفاده این روش رو با شما به اشتراک بذارم.

ارتباط یکی از مهمترین مباحث برای توسعه دهندگان است و از بسیاری جهات قابل انجام است. اما نکته مهم این است که این کار را ساده و بهینه انجام دهیم ما می توانیم این کار را با استفاده از static filed انجام دهیم اما مشکل حافظه رخ می دهد. برای جلوگیری از مشکل حافظه، بسیاری از توسعه دهندگان کارهایی مانند

(activity as MainActivity).passDataToAnotherFragment()

انجام میدهند

آیا با این روش مشکلی  وجود دارد؟

این fragment را با یک activity خاص متصل می کند، قابلیت استفاده مجدد را کاهش می دهد.

پس این روش توصیه شده چیست؟

گوگل توصیه می کند ازinterface (قبل از ViewModel) استفاده کنید. برای این کار ما باید در کلاس Activity آن interface را پیاده سازی کنیم Child fragments یک reference از interface اجرا شده توسط Activity را نگه می دارد. داده ها از طریق متد های interface منتقل می شوند.

fragment- activiti

 

 

 

 

 

 

 

 

 

 

 

بگذارید یک سناریوی ساده را در نظر بگیریم که در آن دو fragment تحت یک activity وجود دارد ، یکی برای وارد کردن یک شماره و دیگری نشان دادن دو برابر ورودی Activity همچنین پیامی را نشان می دهد مثلا ورودی شما 137 است.

 

shared view model

 

 

 

 

 

 

 

 

آیا می توانید تصور کنید که چه کدی و چند سناریو را باید بنویسیم؟

من به جزئیات آن نمی پردازم زیرا این مقاله در مورد ساده ترین راه حل صحبت می کنم نه نشان دادن اجرای interface

راه آسان 

در اینجا ViewModel آمده است تا ما را از دستیابی به سناریوهای زیادی و اجرای interface نجات دهد. ما فقط نیاز به ایجاد کلاس ViewModel داریم ویک instance در fragment ایجاد می کنیم اما Activity Scope استفاده می کنیم تا همه fragment های مربوط به Activity از جمله خود Activity در دسترس باشد.

Communicate between Fragment and Activity using ViewModel

 

جریان کاری ارتباطات با استفاده از ViewModel

 

یک کلاس ViewModel ایجاد کنید

class SharedViewModel:ViewModel(){
    val inputNumber = MutableLiveData<Int>()
}

 

برای انتشار یا انتقال داده ها از fragment ورودی ViewModel را در Activity Scope ایجاد می کنیم. برای این کار activity reference را به عنوان argument از ()ViewModelProvides.of بگذرایم. متد Noe فقط داده ها را به شیء ViewModel مانند این منتقل می کند.

activity?.let {
    sharedViewModel = ViewModelProviders.of(it).get(SharedViewModel::class.java)
}

et_input.addTextChangedListener(object : TextWatcher {
    override fun afterTextChanged(p0: Editable?) {}

    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

    override fun onTextChanged(txt: CharSequence?, p1: Int, p2: Int, p3: Int) {
        txt?.let {
            var input = 0
            if (txt.toString().isNotEmpty()) {
                input = txt.toString().toInt()
            }

            sharedViewModel?.inputNumber?.postValue(input)
        }
    }

 

در Activity ما فقط باید نمونه ای از ViewModel خود ایجاد کنیم و داده های مورد نیاز را مشاهده کنیم.

val sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)

sharedViewModel.inputNumber.observe(this, Observer {
    it?.let {
        // do some thing with the number
    }
})

 

حالا fragment خروجی چطور است؟

برای مشاهده داده ها می توانیم برای fragment خروجی نیز همین کار را انجام دهیم. اما بخاطر داشته باشید که ما باید درActivity Scope، نمونه ViewModel را ایجاد کنیم ، در غیر اینصورت اندروید به جای به اشتراک گذاشتن نمونه مشابه، نمونه جداگانه ایجاد می کند و ما داده ها را دریافت نمی کنیم.

برای fragment خروجی این کار را انجام می دهیم

activity?.let {
    val sharedViewModel = ViewModelProviders.of(it).get(SharedViewModel::class.java)

    sharedViewModel.inputNumber.observe(this, Observer {
        it?.let {
            // do some thing with the number
        }
    })
}

 

کد های این آموزش را میتوانید از لینک زیر دانلود کنید.

https://github.com/maysambabaei/Fragment_viewmodel

تگ‌ها
اشتراک

1 نظرات

  • عکس پروفایل پیمان در سایت باگتو
  • |
  • ارسال شده توسط : پیمان
  • |
  • زمان : 1399/04/26

تا اون قسمتی که یه کلاس ویومدل تعریف می کنیم درسته ولی  اگر بعدش به صورت زیر باشه بهتره

یعنی لازم نیست که ما داخل اکتیویتی چیزی تعریف کنیم که خودش وابستگی ایجاد می کنه و بهتره این کار نشه

فقط کافیه داخل فرگمنت کد زیر رو بزنیم تا لایف سایکل viewModel به اکتیویتی وصل بشه

()private val mViewModel: MyViewModel by activityViewModels

یا راه بهتر وصل کردن اون به یه navGraph است که بهتر و بهینه تر است مثل کد زیر

private val mViewModel: MyViewModel by navGraphViewModels(R.id.my_nav_graph)


 

*قسمت نمایش کدهای سایت هم درست نشون داده نمی شن که اگر direction رو به ltr  کنید درست می شه