نمای کلی LiveData بخشی از Android Jetpack .

LiveData یک کلاس دارنده داده قابل مشاهده است. برخلاف یک قابل مشاهده معمولی، LiveData از چرخه حیات آگاه است، به این معنی که به چرخه حیات سایر اجزای برنامه، مانند فعالیت‌ها، قطعات یا خدمات احترام می‌گذارد. این آگاهی تضمین می کند که LiveData فقط ناظران مؤلفه برنامه را که در حالت چرخه حیات فعال هستند به روز می کند.

LiveData ناظری را که توسط کلاس Observer نشان داده می شود، در حالت فعال در نظر می گیرد اگر چرخه حیات آن در حالت STARTED یا RESUMED باشد. LiveData فقط به ناظران فعال در مورد به روز رسانی ها اطلاع می دهد. ناظران غیرفعال که برای تماشای اشیاء LiveData ثبت نام کرده‌اند، از تغییرات مطلع نمی‌شوند.

شما می توانید یک مشاهده گر جفت شده با یک شی که رابط LifecycleOwner را پیاده سازی می کند، ثبت کنید. این رابطه به ناظر اجازه می دهد تا زمانی که وضعیت شی Lifecycle مربوطه به DESTROYED تغییر می کند، حذف شود. این به ویژه برای فعالیت‌ها و قطعات مفید است، زیرا آنها می‌توانند با خیال راحت اشیاء LiveData را مشاهده کنند و نگران نشت اطلاعات نباشند—فعالیت‌ها و قطعه‌ها بلافاصله پس از از بین رفتن چرخه حیات آنها لغو اشتراک می‌شوند.

برای اطلاعات بیشتر در مورد نحوه استفاده از LiveData، به کار با اشیاء LiveData مراجعه کنید.

مزایای استفاده از LiveData

استفاده از LiveData مزایای زیر را به همراه دارد:

اطمینان حاصل می کند که رابط کاربری شما با وضعیت داده شما مطابقت دارد
LiveData از الگوی ناظر پیروی می کند. LiveData هنگام تغییر داده های اساسی به اشیاء Observer اطلاع می دهد. می توانید کد خود را برای به روز رسانی UI در این اشیاء Observer ادغام کنید. به این ترتیب، لازم نیست هر بار که داده های برنامه تغییر می کند، رابط کاربری را به روز کنید زیرا ناظر این کار را برای شما انجام می دهد.
بدون نشت حافظه
ناظران به اشیاء Lifecycle متصل می شوند و زمانی که چرخه حیات مرتبط با آنها از بین رفت، پس از خود پاکسازی می کنند.
بدون خرابی به دلیل فعالیت های متوقف شده
اگر چرخه حیات ناظر غیرفعال باشد، مثلاً در مورد یک فعالیت در پشته پشتی، هیچ رویداد LiveData را دریافت نمی کند.
دیگر نیازی به دست زدن به چرخه عمر دستی نیست
اجزای UI فقط داده های مربوطه را مشاهده می کنند و مشاهده را متوقف نمی کنند یا از سر نمی گیرند. LiveData به طور خودکار همه اینها را مدیریت می کند زیرا از تغییرات وضعیت چرخه عمر مربوطه هنگام مشاهده آگاه است.
داده های همیشه به روز
اگر یک چرخه حیات غیرفعال شود، پس از فعال شدن مجدد، آخرین داده ها را دریافت می کند. برای مثال، فعالیتی که در پس‌زمینه بود، آخرین داده‌ها را بلافاصله پس از بازگشت به پیش‌زمینه دریافت می‌کند.
تغییرات پیکربندی مناسب
اگر یک فعالیت یا قطعه به دلیل تغییر پیکربندی، مانند چرخش دستگاه، دوباره ایجاد شود، بلافاصله آخرین داده های موجود را دریافت می کند.
به اشتراک گذاری منابع
می‌توانید یک شی LiveData با استفاده از الگوی singleton گسترش دهید تا سرویس‌های سیستم را بپیچانید تا بتوانند در برنامه شما به اشتراک گذاشته شوند. شی LiveData یک بار به سرویس سیستم متصل می شود و سپس هر ناظری که به منبع نیاز دارد می تواند فقط شی LiveData را تماشا کند. برای اطلاعات بیشتر، به Extend LiveData مراجعه کنید.

با اشیاء LiveData کار کنید

برای کار با اشیاء LiveData مراحل زیر را دنبال کنید:

  1. یک نمونه از LiveData برای نگهداری نوع خاصی از داده ایجاد کنید. این معمولا در کلاس ViewModel شما انجام می شود.
  2. یک شی Observer ایجاد کنید که متد onChanged() تعریف می کند، که کنترل می کند چه اتفاقی می افتد زمانی که داده های نگهداری شده LiveData تغییر می کند. شما معمولاً یک شی Observer را در یک کنترلر UI ایجاد می کنید، مانند یک فعالیت یا قطعه.
  3. شی Observer را با استفاده از متد observe() به شی LiveData متصل کنید. observe() یک شی LifecycleOwner می گیرد. این شیء Observer را در شیء LiveData مشترک می کند تا از تغییرات مطلع شود. شما معمولاً شی Observer را در یک کنترلر UI، مانند یک فعالیت یا قطعه، متصل می کنید.

وقتی مقدار ذخیره شده در شی LiveData را به روز می کنید، تا زمانی که LifecycleOwner پیوست شده در حالت فعال باشد، همه ناظران ثبت شده را فعال می کند.

LiveData به ناظران کنترلر رابط کاربری اجازه می دهد تا در به روز رسانی ها مشترک شوند. هنگامی که داده های نگهداری شده توسط شی LiveData تغییر می کند، UI به طور خودکار در پاسخ به روز می شود.

اشیاء LiveData را ایجاد کنید

LiveData پوششی است که می تواند با هر داده ای، از جمله اشیایی که Collections پیاده سازی می کنند، مانند List استفاده شود. یک شی LiveData معمولاً در یک شی ViewModel ذخیره می شود و از طریق یک متد getter قابل دسترسی است، همانطور که در مثال زیر نشان داده شده است:

کاتلین

class NameViewModel : ViewModel() {

    // Create a LiveData with a String
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    // Rest of the ViewModel...
}

جاوا

public class NameViewModel extends ViewModel {

    // Create a LiveData with a String
    private MutableLiveData<String> currentName;

    public MutableLiveData<String> getCurrentName() {
        if (currentName == null) {
            currentName = new MutableLiveData<String>();
        }
        return currentName;
    }

    // Rest of the ViewModel...
}

در ابتدا، داده ها در یک شی LiveData تنظیم نشده اند.

می‌توانید در راهنمای ViewModel درباره مزایا و استفاده از کلاس ViewModel اطلاعات بیشتری کسب کنید.

اشیاء LiveData را مشاهده کنید

در بیشتر موارد، متد onCreate() یک جزء برنامه به دلایل زیر مکان مناسبی برای شروع مشاهده یک شی LiveData است:

  • برای اطمینان از اینکه سیستم از روش onResume() یک اکتیویتی یا قطعه فراخوانی اضافی نمی‌کند.
  • برای اطمینان از اینکه فعالیت یا قطعه دارای داده هایی است که می تواند به محض فعال شدن نمایش داده شود. به محض اینکه یک جزء برنامه در حالت STARTED قرار می گیرد، جدیدترین مقدار را از اشیاء LiveData که مشاهده می کند دریافت می کند. این تنها در صورتی اتفاق می افتد که شی LiveData که باید مشاهده شود تنظیم شده باشد.

به طور کلی، LiveData به‌روزرسانی‌ها را تنها زمانی که داده‌ها تغییر می‌کند و فقط به ناظران فعال ارائه می‌دهد. یک استثنا در این رفتار این است که ناظران نیز هنگامی که از حالت غیرفعال به حالت فعال تغییر می کنند، به روز رسانی دریافت می کنند. علاوه بر این، اگر مشاهده‌گر برای بار دوم از غیرفعال به فعال تغییر کند، فقط در صورتی به‌روزرسانی دریافت می‌کند که مقدار از آخرین باری که فعال شده است تغییر کرده باشد.

کد نمونه زیر نحوه شروع مشاهده یک شی LiveData را نشان می دهد:

کاتلین

class NameActivity : AppCompatActivity() {

    // Use the 'by viewModels()' Kotlin property delegate
    // from the activity-ktx artifact
    private val model: NameViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Other code to setup the activity...

        // Create the observer which updates the UI.
        val nameObserver = Observer<String> { newName ->
            // Update the UI, in this case, a TextView.
            nameTextView.text = newName
        }

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.currentName.observe(this, nameObserver)
    }
}

جاوا

public class NameActivity extends AppCompatActivity {

    private NameViewModel model;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Other code to setup the activity...

        // Get the ViewModel.
        model = new ViewModelProvider(this).get(NameViewModel.class);

        // Create the observer which updates the UI.
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                // Update the UI, in this case, a TextView.
                nameTextView.setText(newName);
            }
        };

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.getCurrentName().observe(this, nameObserver);
    }
}

پس از observe() با nameObserver به عنوان پارامتر، onChanged() بلافاصله فراخوانی می شود و آخرین مقدار ذخیره شده در mCurrentName را ارائه می دهد. اگر شی LiveData مقداری را در mCurrentName تنظیم نکرده باشد، onChanged() فراخوانی نمی شود.

اشیاء LiveData را به روز کنید

LiveData هیچ روش در دسترس عمومی برای به روز رسانی داده های ذخیره شده ندارد. کلاس MutableLiveData متدهای setValue(T) و postValue(T) را به صورت عمومی نشان می دهد و اگر نیاز به ویرایش مقدار ذخیره شده در یک شی LiveData دارید، باید از آنها استفاده کنید. معمولاً MutableLiveData در ViewModel استفاده می شود و سپس ViewModel فقط اشیاء LiveData تغییرناپذیر را در معرض دید ناظران قرار می دهد.

پس از تنظیم رابطه مشاهدهگر، سپس می توانید مقدار شی LiveData را به روز کنید، همانطور که در مثال زیر نشان داده شده است، که وقتی کاربر روی دکمه ای ضربه می زند، همه ناظران را فعال می کند:

کاتلین

button.setOnClickListener {
    val anotherName = "John Doe"
    model.currentName.setValue(anotherName)
}

جاوا

button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        String anotherName = "John Doe";
        model.getCurrentName().setValue(anotherName);
    }
});

فراخوانی setValue(T) در مثال باعث می‌شود ناظران متدهای onChanged() خود را با مقدار John Doe فراخوانی کنند. مثال فشار دادن دکمه را نشان می دهد، اما setValue() یا postValue() می تواند برای به روز رسانی mName به دلایل مختلفی فراخوانی شود، از جمله در پاسخ به درخواست شبکه یا بارگذاری پایگاه داده تکمیل می شود. در همه موارد، فراخوانی به setValue() یا postValue() ناظران را فعال می کند و UI را به روز می کند.

از LiveData با Room استفاده کنید

کتابخانه تداوم اتاق از پرس و جوهای قابل مشاهده پشتیبانی می کند که اشیاء LiveData را برمی گرداند. پرس و جوهای قابل مشاهده به عنوان بخشی از یک شی دسترسی به پایگاه داده (DAO) نوشته می شوند.

اتاق تمام کدهای لازم برای به روز رسانی شی LiveData هنگام به روز رسانی پایگاه داده تولید می کند. کد تولید شده در صورت نیاز پرس و جو را به صورت ناهمزمان بر روی یک رشته پس زمینه اجرا می کند. این الگو برای همگام نگه داشتن داده های نمایش داده شده در رابط کاربری با داده های ذخیره شده در پایگاه داده مفید است. می‌توانید در راهنمای کتابخانه دائمی اتاق درباره اتاق و DAO اطلاعات بیشتری کسب کنید.

از کوروتین ها با LiveData استفاده کنید

LiveData شامل پشتیبانی از کوروتین های Kotlin است. برای اطلاعات بیشتر، استفاده از کوروتین های Kotlin با اجزای معماری Android را ببینید.

LiveData در معماری یک برنامه

LiveData از چرخه حیات آگاه است و از چرخه حیات موجودیت هایی مانند فعالیت ها و قطعات پیروی می کند. از LiveData برای برقراری ارتباط بین مالکان چرخه حیات و سایر اشیاء با طول عمر متفاوت مانند اشیاء ViewModel استفاده کنید. مسئولیت اصلی ViewModel بارگذاری و مدیریت داده های مرتبط با رابط کاربری است که آن را به یک نامزد عالی برای نگهداری اشیاء LiveData تبدیل می کند. اشیاء LiveData را در ViewModel ایجاد کنید و از آنها برای نمایش وضعیت در لایه UI استفاده کنید.

فعالیت‌ها و قطعات نباید نمونه‌های LiveData را نگه دارند زیرا نقش آن‌ها نمایش داده‌ها است نه حالت نگه‌داشتن. همچنین، دور نگه داشتن فعالیت ها و قطعات از نگهداری داده ها، نوشتن تست های واحد را آسان تر می کند.

ممکن است کار کردن با اشیاء LiveData در کلاس لایه داده وسوسه انگیز باشد، اما LiveData برای مدیریت جریان های ناهمزمان داده طراحی نشده است. حتی اگر می‌توانید از تبدیل‌های LiveData و MediatorLiveData برای رسیدن به این هدف استفاده کنید، این رویکرد دارای اشکالاتی است: قابلیت ترکیب جریان‌های داده بسیار محدود است و تمام اشیاء LiveData (از جمله مواردی که از طریق تبدیل‌ها ایجاد می‌شوند) در رشته اصلی مشاهده می‌شوند. کد زیر نمونه ای از نحوه نگهداری LiveData در Repository است که می تواند رشته اصلی را مسدود کند:

کاتلین

class UserRepository {

    // DON'T DO THIS! LiveData objects should not live in the repository.
    fun getUsers(): LiveData<List<User>> {
        ...
    }

    fun getNewPremiumUsers(): LiveData<List<User>> {
        return getUsers().map { users ->
            // This is an expensive call being made on the main thread and may
            // cause noticeable jank in the UI!
            users
                .filter { user ->
                  user.isPremium
                }
          .filter { user ->
              val lastSyncedTime = dao.getLastSyncedTime()
              user.timeCreated > lastSyncedTime
                }
    }
}

جاوا

class UserRepository {

    // DON'T DO THIS! LiveData objects should not live in the repository.
    LiveData<List<User>> getUsers() {
        ...
    }

    LiveData<List<User>> getNewPremiumUsers() {
    return Transformations.map(getUsers(),
        // This is an expensive call being made on the main thread and may cause
        // noticeable jank in the UI!
        users -> users.stream()
            .filter(User::isPremium)
            .filter(user ->
                user.getTimeCreated() > dao.getLastSyncedTime())
            .collect(Collectors.toList()));
    }
}

اگر نیاز به استفاده از جریان‌های داده در لایه‌های دیگر برنامه خود دارید، از Kotlin Flow استفاده کنید و سپس با استفاده از asLiveData() آنها را به LiveData در ViewModel تبدیل کنید. در مورد استفاده از Kotlin Flow با LiveData در این Codelab بیشتر بیاموزید. برای پایگاه‌های کد ساخته شده با جاوا، استفاده از Executors را همراه با callbacks یا RxJava در نظر بگیرید.

LiveData را گسترش دهید

LiveData یک ناظر را در حالت فعال در نظر می گیرد اگر چرخه زندگی ناظر در حالت STARTED یا RESUMED باشد. کد نمونه زیر نحوه گسترش کلاس LiveData را نشان می دهد:

کاتلین

class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
    private val stockManager = StockManager(symbol)

    private val listener = { price: BigDecimal ->
        value = price
    }

    override fun onActive() {
        stockManager.requestPriceUpdates(listener)
    }

    override fun onInactive() {
        stockManager.removeUpdates(listener)
    }
}

جاوا

public class StockLiveData extends LiveData<BigDecimal> {
    private StockManager stockManager;

    private SimplePriceListener listener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);
        }
    };

    public StockLiveData(String symbol) {
        stockManager = new StockManager(symbol);
    }

    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);
    }

    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);
    }
}

پیاده سازی قیمت شنونده در این مثال شامل روش های مهم زیر است:

  • متد onActive() زمانی فراخوانی می شود که شی LiveData یک ناظر فعال داشته باشد. این بدان معناست که باید از این روش شروع به مشاهده به روز رسانی قیمت سهام کنید.
  • متد onInactive() زمانی فراخوانی می شود که شی LiveData هیچ ناظر فعالی نداشته باشد. از آنجایی که هیچ ناظری گوش نمی دهد، دلیلی برای اتصال به سرویس StockManager وجود ندارد.
  • متد setValue(T) مقدار نمونه LiveData را به روز می کند و هر ناظر فعال را در مورد تغییر مطلع می کند.

می توانید از کلاس StockLiveData به صورت زیر استفاده کنید:

کاتلین

public class MyFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val myPriceListener: LiveData<BigDecimal> = ...
        myPriceListener.observe(viewLifecycleOwner, Observer<BigDecimal> { price: BigDecimal? ->
            // Update the UI.
        })
    }
}

جاوا

public class MyFragment extends Fragment {
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        LiveData<BigDecimal> myPriceListener = ...;
        myPriceListener.observe(getViewLifecycleOwner(), price -> {
            // Update the UI.
        });
    }
}

متد observe() LifecycleOwner مرتبط با نمای قطعه را به عنوان اولین آرگومان ارسال می کند. انجام این کار نشان می دهد که این ناظر به شی Lifecycle مرتبط با مالک متصل است، به این معنی:

  • اگر شی Lifecycle در حالت فعال نباشد، مشاهده گر فراخوانی نمی شود حتی اگر مقدار تغییر کند.
  • پس از از بین رفتن شی Lifecycle ، ناظر به طور خودکار حذف می شود.

این واقعیت که اشیاء LiveData از چرخه حیات آگاه هستند به این معنی است که شما می توانید آنها را بین چندین فعالیت، قطعات و خدمات به اشتراک بگذارید. برای ساده نگه داشتن مثال، می توانید کلاس LiveData را به صورت تکی به صورت زیر پیاده سازی کنید:

کاتلین

class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
    private val stockManager: StockManager = StockManager(symbol)

    private val listener = { price: BigDecimal ->
        value = price
    }

    override fun onActive() {
        stockManager.requestPriceUpdates(listener)
    }

    override fun onInactive() {
        stockManager.removeUpdates(listener)
    }

    companion object {
        private lateinit var sInstance: StockLiveData

        @MainThread
        fun get(symbol: String): StockLiveData {
            sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
            return sInstance
        }
    }
}

جاوا

public class StockLiveData extends LiveData<BigDecimal> {
    private static StockLiveData sInstance;
    private StockManager stockManager;

    private SimplePriceListener listener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);
        }
    };

    @MainThread
    public static StockLiveData get(String symbol) {
        if (sInstance == null) {
            sInstance = new StockLiveData(symbol);
        }
        return sInstance;
    }

    private StockLiveData(String symbol) {
        stockManager = new StockManager(symbol);
    }

    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);
    }

    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);
    }
}

و می توانید از آن در قطعه به صورت زیر استفاده کنید:

کاتلین

class MyFragment : Fragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        StockLiveData.get(symbol).observe(viewLifecycleOwner, Observer<BigDecimal> { price: BigDecimal? ->
            // Update the UI.
        })

    }

جاوا

public class MyFragment extends Fragment {
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        StockLiveData.get(symbol).observe(getViewLifecycleOwner(), price -> {
            // Update the UI.
        });
    }
}

قطعات و فعالیت های متعدد می توانند نمونه MyPriceListener را مشاهده کنند. LiveData تنها در صورتی به سرویس سیستم متصل می شود که یک یا چند مورد از آنها قابل مشاهده و فعال باشند.

تبدیل LiveData

ممکن است بخواهید تغییراتی در مقدار ذخیره شده در یک شی LiveData قبل از ارسال آن به ناظران ایجاد کنید، یا ممکن است لازم باشد یک نمونه LiveData متفاوت را بر اساس مقدار مورد دیگر برگردانید. بسته Lifecycle کلاس Transformations ارائه می دهد که شامل متدهای کمکی است که از این سناریوها پشتیبانی می کنند.

Transformations.map()
تابعی را روی مقدار ذخیره شده در شی LiveData اعمال می کند و نتیجه را در پایین دست منتشر می کند.

کاتلین

val userLiveData: LiveData<User> = UserLiveData()
val userName: LiveData<String> = userLiveData.map {
    user -> "${user.name} ${user.lastName}"
}

جاوا

LiveData<User> userLiveData = ...;
LiveData<String> userName = Transformations.map(userLiveData, user -> {
    user.name + " " + user.lastName
});
Transformations.switchMap()
مشابه map() ، تابعی را برای مقدار ذخیره شده در شی LiveData اعمال می کند و نتیجه را باز می کند و به پایین دست ارسال می کند. تابع ارسال شده به switchMap() باید یک شی LiveData را برگرداند، همانطور که در مثال زیر نشان داده شده است:

کاتلین

private fun getUser(id: String): LiveData<User> {
  ...
}
val userId: LiveData<String> = ...
val user = userId.switchMap { id -> getUser(id) }

جاوا

private LiveData<User> getUser(String id) {
  ...;
}

LiveData<String> userId = ...;
LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );

شما می توانید از روش های تبدیل برای انتقال اطلاعات در طول چرخه حیات ناظر استفاده کنید. تبدیل ها محاسبه نمی شوند مگر اینکه یک ناظر در حال تماشای شی LiveData برگشتی باشد. از آنجایی که تبدیل ها به صورت تنبل محاسبه می شوند، رفتارهای مرتبط با چرخه عمر به طور ضمنی بدون نیاز به فراخوانی یا وابستگی های صریح اضافی منتقل می شوند.

اگر فکر می کنید که به یک شی Lifecycle در داخل یک شی ViewModel نیاز دارید، احتمالاً یک تبدیل راه حل بهتری است. به عنوان مثال، فرض کنید یک مؤلفه رابط کاربری دارید که یک آدرس را می‌پذیرد و کد پستی آن آدرس را برمی‌گرداند. همانطور که در کد نمونه زیر نشان داده شده است، می‌توانید ViewModel ساده‌لوح را برای این مؤلفه پیاده‌سازی کنید:

کاتلین

class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {

    private fun getPostalCode(address: String): LiveData<String> {
        // DON'T DO THIS
        return repository.getPostCode(address)
    }
}

جاوا

class MyViewModel extends ViewModel {
    private final PostalCodeRepository repository;
    public MyViewModel(PostalCodeRepository repository) {
       this.repository = repository;
    }

    private LiveData<String> getPostalCode(String address) {
       // DON'T DO THIS
       return repository.getPostCode(address);
    }
}

سپس مؤلفه UI باید هر بار که getPostalCode() را فراخوانی می کند، از شی قبلی LiveData لغو ثبت نام کرده و در نمونه جدید ثبت شود. علاوه بر این، اگر مؤلفه UI دوباره ایجاد شود، به جای استفاده از نتیجه تماس قبلی، فراخوانی دیگری را با متد repository.getPostCode() راه اندازی می کند.

در عوض، می‌توانید جستجوی کد پستی را به‌عنوان تبدیل ورودی آدرس پیاده‌سازی کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
    private val addressInput = MutableLiveData<String>()
    val postalCode: LiveData<String> = addressInput.switchMap {
            address -> repository.getPostCode(address) }


    private fun setInput(address: String) {
        addressInput.value = address
    }
}

جاوا

class MyViewModel extends ViewModel {
    private final PostalCodeRepository repository;
    private final MutableLiveData<String> addressInput = new MutableLiveData();
    public final LiveData<String> postalCode =
            Transformations.switchMap(addressInput, (address) -> {
                return repository.getPostCode(address);
             });

  public MyViewModel(PostalCodeRepository repository) {
      this.repository = repository
  }

  private void setInput(String address) {
      addressInput.setValue(address);
  }
}

در این مورد، قسمت postalCode به عنوان تبدیل addressInput تعریف می شود. تا زمانی که برنامه شما یک ناظر فعال مرتبط با فیلد postalCode داشته باشد، مقدار فیلد هر زمان که addressInput تغییر کند دوباره محاسبه و بازیابی می‌شود.

این مکانیسم به سطوح پایین‌تر برنامه اجازه می‌دهد تا اشیاء LiveData را ایجاد کند که به‌طور تنبلی در صورت تقاضا محاسبه می‌شوند. یک شی ViewModel می تواند به راحتی ارجاعاتی به اشیاء LiveData بدست آورد و سپس قوانین تبدیل را در بالای آنها تعریف کند.

تحولات جدید ایجاد کنید

ده ها تغییر خاص مختلف وجود دارد که ممکن است در برنامه شما مفید باشد، اما به طور پیش فرض ارائه نشده اند. برای پیاده سازی تغییر شکل خود می توانید از کلاس MediatorLiveData استفاده کنید که به دیگر اشیاء LiveData گوش می دهد و رویدادهای منتشر شده توسط آنها را پردازش می کند. MediatorLiveData وضعیت خود را به درستی به شی منبع LiveData منتشر می کند. برای آشنایی بیشتر با این الگو، به مستندات مرجع کلاس Transformations مراجعه کنید.

چندین منبع LiveData را ادغام کنید

MediatorLiveData یک زیر کلاس از LiveData است که به شما امکان می دهد چندین منبع LiveData را ادغام کنید. ناظرهای اشیاء MediatorLiveData سپس هر زمان که هر یک از اشیاء منبع اصلی LiveData تغییر کند فعال می شوند.

به عنوان مثال، اگر یک شی LiveData در رابط کاربری خود دارید که می تواند از یک پایگاه داده محلی یا یک شبکه به روز شود، می توانید منابع زیر را به شی MediatorLiveData اضافه کنید:

  • یک شی LiveData مرتبط با داده های ذخیره شده در پایگاه داده.
  • یک شی LiveData مرتبط با داده های قابل دسترسی از شبکه.

فعالیت شما فقط باید شی MediatorLiveData را مشاهده کند تا به‌روزرسانی‌ها را از هر دو منبع دریافت کند. برای مثالی دقیق، بخش Addendum: exposuring network status در راهنمای معماری برنامه را ببینید.

منابع اضافی

برای کسب اطلاعات بیشتر در مورد کلاس LiveData ، به منابع زیر مراجعه کنید.

نمونه ها

Codelabs

وبلاگ ها

ویدیوها

{% کلمه به کلمه %} {% آخر کلمه %} {% کلمه به کلمه %} {% آخر کلمه %}