簡體   English   中英

將查詢參數傳遞給 Android 應用程序中的 LiveData/Viewmodel

[英]Passing query parameters to LiveData/Viewmodel in Android app

由於我是 Android 應用程序編程新手,因此我遵循了有關如何使用 Android 架構組件和 Firebase 來實現 MVVM(使用 LiveData、ViewModel 等)的教程。

我遵循的教程可以在這里找到:

我現在剩下的是我認為 MVVM 的一個不錯的實現,但是我無法理解我應該如何將查詢參數傳遞給它。 現在我需要對要檢索的文檔的 ID 進行硬編碼:

public class AlarmDAO {

    private FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();

    public AlarmLiveData getFirestoreLiveData() {
        DocumentReference documentReference = firebaseFirestore.collection(Collection.ALARMS.name).document("5RxJNuNyhDJlz49wpBkw");

        return new AlarmLiveData(documentReference);
    }

}

然后由擴展ViewModel的類調用。

public class AlarmViewModel extends ViewModel {

    private AlarmDAO DAO = new AlarmDAO();
    private AlarmLiveData liveData = null;

    public LiveData<Alarm> getAlarmLiveData() {
        liveData = DAO.getFirestoreLiveData();
        return liveData;
    }

    public LiveData<Alarm> getAlarm() {
        return liveData.alarm;
    }

}

然后我在我的活動中觀察這些數據:

model.getAlarmLiveData().observe(this, Observable -> {});
model.getAlarm().observe(this, alarm -> {
   if (alarm != null) {
      alarmTextView.setText(alarm.getTest());
   else {
      Log.d(TAG, "Waiting for data");
   }
});

我的問題是我沒有看到查詢特定警報的方法。 例如model.getAlarm("someId") 我的印象是它應該在 DAO 和/或 ViewModel 中完成,但我不知道如何完成。 我不明白的另一件事是為什么我需要在我的活動中同時觀察model.getAlarmLiveData()model.getAlarm() ,因為只使用一個不起作用。 這兩個問題的答案很可能非常簡單,但到目前為止我還沒有弄清楚。

為了完整AlarmLiveData :除了兩個字符串的 getter 和 setter 之外, Alarm類什么也沒有,下面是AlarmLiveData類。

public class AlarmLiveData extends LiveData<Alarm> implements EventListener<DocumentSnapshot> {

    private static final String TAG = AlarmLiveData.class.getSimpleName();

    private Alarm alarmTemp = new Alarm();
    private DocumentReference documentReference;
    private ListenerRegistration listenerRegistration = () -> {};

    public MutableLiveData<Alarm> alarm = new MutableLiveData<>();

    public AlarmLiveData(DocumentReference documentReference) {
        this.documentReference = documentReference;
    }

    @Override
    protected void onActive() {
        listenerRegistration = documentReference.addSnapshotListener(this);
        super.onActive();
    }

    @Override
    protected void onInactive() {
        listenerRegistration.remove();
        super.onInactive();
    }


    @Override
    public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
        if (documentSnapshot != null && documentSnapshot.exists()) {
            alarmTemp = new Alarm();
            alarmTemp.setId(documentSnapshot.getId());
            alarmTemp.setTest(documentSnapshot.get("test").toString());
            alarm.setValue(alarmTemp);
        } else {
            Log.d(TAG, "ERROR");
        }
    }
}

感謝閱讀,期待答案!

您必須同時使用model.getAlarmLiveData()model.getAlarm()似乎是您的 AlarmLiveData 類擴展了 LiveData 但為包含的 MutableLiveData 成員變量設置了一個值,而不是設置其自己的類值。

在您的 AlarmLiveData 類中:

// Comment out/Remove your 'public MutableLiveData<alarm> alarm' member variable from the top.
// You're going to want to set the value of the AlarmLiveData class itself instead.

// ...

// Then inside of your onEvent callback
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
    if (documentSnapshot != null && documentSnapshot.exists()) {
        alarmTemp = new Alarm();
        alarmTemp.setId(documentSnapshot.getId());
        alarmTemp.setTest(documentSnapshot.get("test").toString());
        
        // Set the value for the AlarmLiveData class directly
        setValue(alarmTemp);
    } else {
        Log.d(TAG, "ERROR");
    }
}

我不確定您為什么要創建 DAO 類,我很可能會將該代碼直接移到 AlarmViewModel 類中。 但是,如果您不想刪除它,您可以通過以下方式更改當前的 DAO 類:

// Pass in the document id you want to create a document reference for
public AlarmLiveData getFirestoreLiveData(String documentId) {
    DocumentReference documentReference = firebaseFirestore.collection(Collection.ALARMS.name).document(documentId);

    return new AlarmLiveData(documentReference);
}

您的 AlarmViewModel 類將如下所示:

public class AlarmViewModel extends ViewModel {

    private AlarmDAO DAO = new AlarmDAO();
    private AlarmLiveData liveData = null;

    // Make sure to take in the document id so you can create the corresponding LiveData
    public LiveData<Alarm> getAlarmLiveData(String documentId) {
        // Only create a new LiveData instance if the current one is null.
        // This is helpful if you intend to use this as a Shared ViewModel.
        if(liveData == null){
            liveData = DAO.getFirestoreLiveData(documentId);
        }
        
        return liveData;
    }
}

最后,在您的活動中:

// Pass in the document id and observe the ViewModel
model.getAlarmLiveData("MY_DOCUMENT_ID").observe(this, alarm -> {
   if (alarm != null) {
      alarmTextView.setText(alarm.getTest());
   }else{
      Log.d(TAG, "Waiting for data");
   }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM