gpt4 book ai didi

mvvm - 如何在ViewModel层上将普通数据(从房间返回)转换为LiveData

转载 作者:行者123 更新时间:2023-12-03 10:42:27 25 4
gpt4 key购买 nike

我使用带有MVVM模式的干净架构,因此房间部分进入数据层,并将可观察对象从那里返回到域层,并将它们包装在LiveData中,从而在表示层中使用它们。
现在,问题是插入/删除/更新后,列表没有立即在UI中更新。

表示层中的 View 模型:

public class WordViewModel extends BaseViewModel<WordNavigator> {

//get all the use cases here
private GetAllWords getAllWords;
private InsertWord insertWord;
private DeleteThisWord deleteThisWord;
private UpdateThisWord updateThisWord;
private GetTheIndexOfTopWord getTheIndexOfTopWord;

//data
public MutableLiveData<List<Word>> allWords;


public WordViewModel(GetAllWords getAllWords, InsertWord insertWord, DeleteThisWord deleteThisWord, UpdateThisWord updateThisWord, GetTheIndexOfTopWord getTheIndexOfTopWord) {
this.getAllWords = getAllWords;
this.insertWord = insertWord;
this.deleteThisWord = deleteThisWord;
this.updateThisWord = updateThisWord;
this.getTheIndexOfTopWord = getTheIndexOfTopWord;
}

public void getAllWords() {
getAllWords.execute(new DisposableObserver<List<Word>>() {
@Override
public void onNext(List<Word> words) {
allWords.setValue(words);
}

@Override
public void onError(Throwable e) {

}

@Override
public void onComplete() {

}
}, GetAllWords.Params.getAllWords());
}


public void insertWord(Word word) {
insertWord.execute(new DisposableObserver<Boolean>() {
@Override
public void onNext(Boolean aBoolean) {
if (aBoolean)
Log.e("ganesh", "word inserted successfully!!!");
}

@Override
public void onError(Throwable e) {
e.printStackTrace();
}

@Override
public void onComplete() {

}
}, InsertWord.Params.insertWord(word));

}

public void getTheIndexOfTopWord(final String action) {
getTheIndexOfTopWord.execute(new DisposableObserver<Word>() {
@Override
public void onNext(Word word) {
if (word != null)
getNavigator().updateTopIndex(word.getWordId(), action);
}

@Override
public void onError(Throwable e) {
e.printStackTrace();
}

@Override
public void onComplete() {

}
}, GetTheIndexOfTopWord.Params.getTheIndexOfTopWord());
}

public void deleteThisWord(int wordId) {
deleteThisWord.execute(new DisposableObserver<Boolean>() {
@Override
public void onNext(Boolean aBoolean) {
if (aBoolean)
Log.e("ganesh", "word deleted successfully!!!");
}

@Override
public void onError(Throwable e) {
e.printStackTrace();
}

@Override
public void onComplete() {

}
}, DeleteThisWord.Params.deleteThisWord(wordId));
}

public void updateThisWord(int wordId, String newWord) {
updateThisWord.execute(new DisposableObserver<Boolean>() {
@Override
public void onNext(Boolean aBoolean) {
if (aBoolean)
Log.e("ganesh", "word updated successfully!!!");
}

@Override
public void onError(Throwable e) {
e.printStackTrace();
}

@Override
public void onComplete() {

}
}, UpdateThisWord.Params.updateThisWord(wordId, newWord));
}

public MutableLiveData<List<Word>> getWords() {
if (allWords == null) {
allWords = new MutableLiveData<>();
}
return allWords;
}

@Override
protected void onCleared() {
super.onCleared();

if (getAllWords != null)
getAllWords = null;
if (deleteThisWord != null)
deleteThisWord = null;
if (insertWord != null)
insertWord = null;
if (updateThisWord != null)
updateThisWord = null;
if (getTheIndexOfTopWord != null)
getTheIndexOfTopWord = null;

}
}

数据层中的DAO:
@Dao
public interface WordDao {
@Insert
void insertThisWord(Word word);

@Query("delete from word_table")
void deleteAll();

@Query("select * from word_table order by word_id asc")
List<Word> getAllWords();

@Query("delete from word_table where word_id = :wordId")
void deleteThisWord(int wordId);

@Query("update word_table set word = :newWord where word_id = :wordId")
void updateThisWord(int wordId, String newWord);

@Query("select * from word_table order by word_id asc limit 1")
Word getTheIndexOfTopWord();
}

数据层中的存储库:
public class WordRepositoryImpl implements WordRepository {

private ApiInterface apiInterface;
private SharedPreferenceHelper sharedPreferenceHelper;
private Context context;

private WordDao wordDao;
private WordRoomDatabase db;

public WordRepositoryImpl(ApiInterface apiInterface, SharedPreferenceHelper sharedPreferenceHelper, WordRoomDatabase db, Context context) {
this.apiInterface = apiInterface;
this.sharedPreferenceHelper = sharedPreferenceHelper;
this.context = context;
this.db = db;
wordDao = db.wordDao();
}


@Override
public Observable<Integer> sum(final int a, final int b) {
return Observable.fromCallable(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return (a + b);
}
});
}

@Override
public Observable<List<Word>> getAllWords() {
return Observable.fromCallable(new Callable<List<Word>>() {
@Override
public List<Word> call() throws Exception {
List<Word> list = new ArrayList<>();
List<com.example.data.models.Word> listWords = db.wordDao().getAllWords();
for (com.example.data.models.Word item : listWords) {
list.add(new Word(item.getWordId(), item.getWord(), item.getWordLength()));
}
return list;
}
});
}

@Override
public Observable<Boolean> insertThisWord(final Word word) {
return Observable.fromCallable(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
com.example.data.models.Word item = new com.example.data.models.Word(word.getWord(), word.getWordLength());
db.wordDao().insertThisWord(item);
return true;
}
});
}

@Override
public Observable<Boolean> deleteThisWord(final int wordId) {
return Observable.fromCallable(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
db.wordDao().deleteThisWord(wordId);
return true;
}
});
}

@Override
public Observable<Boolean> updateThisWord(final int wordId, final String newWord) {
return Observable.fromCallable(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
db.wordDao().updateThisWord(wordId, newWord);
return true;
}
});
}

@Override
public Observable<Word> getTheIndexOfTopWord() {
return Observable.fromCallable(new Callable<Word>() {
@Override
public Word call() throws Exception {
com.example.data.models.Word item = db.wordDao().getTheIndexOfTopWord();
Word word = new Word(item.getWordId(), item.getWord(), item.getWordLength());
return word;
}
});
}
}

域层中的GetAllWordsUseCase:
public class GetAllWords extends UseCase<List<Word>, GetAllWords.Params> {

private WordRepository wordRepository;

public GetAllWords(PostExecutionThread postExecutionThread, WordRepository wordRepository) {
super(postExecutionThread);
this.wordRepository = wordRepository;
}

@Override
public Observable<List<Word>> buildUseCaseObservable(Params params) {
return wordRepository.getAllWords();
}

public static final class Params {
private Params() {
}

public static GetAllWords.Params getAllWords() {
return new GetAllWords.Params();
}
}
}

域层中的UseCase基类:
public abstract class UseCase<T, Params> {

private final PostExecutionThread postExecutionThread;
private final CompositeDisposable compositeDisposable;

public UseCase(PostExecutionThread postExecutionThread) {
this.postExecutionThread = postExecutionThread;
this.compositeDisposable = new CompositeDisposable();
}

/**
* Builds an {@link Observable} which will be used when executing the current {@link UseCase}.
*/
public abstract Observable<T> buildUseCaseObservable(Params params);

/**
* Dispose from current {@link CompositeDisposable}.
*/
public void dispose() {
if (!compositeDisposable.isDisposed()) {
compositeDisposable.dispose();
}
}

/**
* Executes the current use case.
*
* @param observer {@link DisposableObserver} which will be listening to the observable build
* by {@link #buildUseCaseObservable(Params)} ()} method.
* @param params Parameters (Optional) used to build/execute this use case.
*/
public void execute(DisposableObserver<T> observer, Params params) {
if (observer != null) {
final Observable<T> observable = this.buildUseCaseObservable(params)
.subscribeOn(Schedulers.io())
.observeOn(postExecutionThread.getScheduler());
addDisposable(observable.subscribeWith(observer));
}
}

/**
* Dispose from current {@link CompositeDisposable}.
*/
private void addDisposable(Disposable disposable) {
if (disposable != null && compositeDisposable != null)
compositeDisposable.add(disposable);
}
}

最后,表示层中的WordActivity
public class WordActivity extends BaseActivity<WordViewModel> implements 
View.OnClickListener, WordNavigator {

@Inject
WordViewModel wordViewModel;

private Button deleteButton, updateButton, addButton;
private EditText editTextWord;
private WordListAdapter adapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_word);
((MainApplication) getApplicationContext()).getComponent().inject(this);
editTextWord = findViewById(R.id.activity_word_et_word);
deleteButton = findViewById(R.id.activity_main_delete_button);
updateButton = findViewById(R.id.activity_main_update_button);
addButton = findViewById(R.id.activity_word_btn_add_word);

deleteButton.setOnClickListener(this);
updateButton.setOnClickListener(this);
addButton.setOnClickListener(this);


RecyclerView recyclerView = findViewById(R.id.recyclerview);
adapter = new WordListAdapter(this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

getViewModel().setNavigator(this);

getViewModel().getAllWords();

getViewModel().getWords().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(@android.support.annotation.Nullable List<Word> words) {
adapter.setWords(words);
}
});

}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.activity_main_delete_button:
getViewModel().getTheIndexOfTopWord(TOP_INDEX_ACTION_DELETE);
break;
case R.id.activity_main_update_button:
getViewModel().getTheIndexOfTopWord(TOP_INDEX_ACTION_UPDATE);
break;
case R.id.activity_word_btn_add_word:
handleAddButtonClick();
break;
}
}

public void handleAddButtonClick() {
String text = editTextWord.getText().toString();
if (text.equals("")) {
Toast.makeText(getApplicationContext(), R.string.empty_not_saved, Toast.LENGTH_LONG).show();
} else {
Word word = new Word(text, text.length());
getViewModel().insertWord(word);
editTextWord.setText("");
editTextWord.clearFocus();
}
}

@Override
public void updateTopIndex(Integer wordId, String action) {
if (action.equals(TOP_INDEX_ACTION_DELETE))
getViewModel().deleteThisWord(wordId);
else
getViewModel().updateThisWord(wordId, "dsakagdad");
}

@Override
public WordViewModel getViewModel() {
return wordViewModel;
}
}


**getViewModel().getWords().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(@android.support.annotation.Nullable List<Word> words) {
adapter.setWords(words);
}
});**

//This portion is getting called only once but not when I
insert/update/delete words from room database!

任何人都可以通过这些帮助我!

最佳答案

DAO中的此方法将查询列表,并像普通的SQL查询一样返回:

@Query("select * from word_table order by word_id asc")
List<Word> getAllWords();

如果您想观察变化,则可能需要考虑使用RxJava2的 Flowable/ObservableLiveData

我更喜欢RxJava方法,它看起来像这样:
@Query("select * from word_table order by word_id asc")
Flowable<List<Word>> getAllWords();
// or
Observable<List<Word>> getAllWords();

Difference between Flowable and Observable

完成此操作后,您可能想要在存储库中更改 getAllWords方法以返回该 Flowable/Observable

注意:使用 ObservableFlowable都将首先发出一次查询结果,然后开始观察进一步的更改,直到取消订阅为止。

Read more about Room with RxJava

关于mvvm - 如何在ViewModel层上将普通数据(从房间返回)转换为LiveData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52093598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com