问题描述
也许我误解了这一切,但是您如何使用实时数据/视图模型/存储库编辑数据?我看到如何查询所有数据,删除条目,但我想编辑特定字段。
例如,我正在跟踪 3 件事。日期、时间和类别。我需要能够更改类别。
我尝试在我的一项活动中做这样的事情:
budgetviewmodel.getAllEntries().observe(this,new Observer<List<BudgetEntry>>() {
@Override
public void onChanged(List<BudgetEntry> budgetEntries) {
Log.i(TAG,"2nd Observer is going off");
if (manualUpdate == 1) {
Log.i(TAG,"MANUAL UPDATE");
budgetEntries.get(0).setCategory(updatedCategory);
manualUpdate = 0;
Log.i(TAG,"Budget Entries: " + budgetEntries.get(0).getCategory());
}
else {
Log.i(TAG,"No change");
}
}
});
}
}
但它不会永久改变它。我猜只是在这种情况下,因为日志显示我更改了类别,但是当我重新加载应用程序或检查另一个活动时,它仍然显示先前的数据。
我找不到任何有关此的教程,因此非常感谢您的指导!
新的视图模型更改。我收到错误无法创建类的实例:
公共类 Budgetviewmodel 扩展了 Androidviewmodel {
private BudgetRepository budgetRepository;
//private LiveData<List<BudgetEntry>> allEntries;
LiveData<List<BudgetEntry>> _allEntries = budgetRepository.getAllEntries();
LiveData<List<BudgetEntry>> allEntries = Transformations.map(_allEntries,new Function<List<BudgetEntry>,List<BudgetEntry>>() {
@Override
public List<BudgetEntry> apply(List<BudgetEntry> input) {
return input;
}
});
public Budgetviewmodel(@NonNull Application application) {
super(application);
budgetRepository = new BudgetRepository(application);
//allEntries = budgetRepository.getAllEntries();
}
public void insert (BudgetEntry budgetEntry) {
budgetRepository.insert(budgetEntry);
}
public void delete (BudgetEntry budgetEntry) {
budgetRepository.delete(budgetEntry);
}
public void deleteallEntries () {
budgetRepository.deleteallEntries();
}
public LiveData<List<BudgetEntry>> getAllEntries() {
return _allEntries;
}
public LiveData<Integer> getCount() {
return budgetRepository.getCount();
}
}
谢谢!
解决方法
为此,您可以在 ViewModel 中使用 Transformations.map 函数。
将主线程上的给定函数应用于源 LiveData 发出的每个值,并返回 LiveData,后者发出结果值。
给定的函数 func 将在主线程上执行。
科特林
import androidx.lifecycle.*
class YourViewModel : ViewModel() {
private val _allEntries: LiveData<List<BudgetEntry>> = budgetRepository.getAllEntries()
val allEntries: LiveData<List<BudgetEntry>> = Transformations.map(_allEntries) { list: List<BudgetEntry> ->
list.map { budgetEntry ->
budgetEntry.setCategory(updatedCategorya)
}
}
}
Java
import androidx.lifecycle.*;
class YourViewModel extends ViewModel {
private final LiveData<List<BudgetEntry>> _allEntries = budgetRepository.getAllEntries();
final LiveData<List<BudgetEntry>> allEntries = Transformations.map(_allEntries,new Function<List<BudgetEntry>,List<BudgetEntry>>() {
@Override
public List<BudgetEntry> apply(List<BudgetEntry> input) {
// do the mapping for each budgetEntry
return // mapped list
}
});
}
现在您可以照常观察 allEntries
。 map
函数负责更新 LiveData。
我终于明白了,哇哦!我无法得到 Transformation 的答案,所以我开始研究如何使用 @Update。我想分享一下,以防将来对某人有所帮助,因为这花了我几个星期。 :)
我在我的模型中跟踪了 3 件事。类别、日期、时间。我的目标是能够将与特定字符串匹配的所有类别名称更改为新字符串。
首先,您需要在模型中命名您的列:
@ColumnInfo(name="CATEGORY") 私有字符串类别;
然后您需要在您的 DAO 中创建一个 SQL 查询来查找并使用新类别更新旧类别:
@Query("UPDATE entry SET CATEGORY = :newcategory WHERE category = :oldcategory")
void updateColumn(String newcategory,String oldcategory);
这基本上是说找到与字符串匹配的所有类别,并将它们更新为您的新字符串。
现在您需要在视图模型和存储库中创建方法。
我们将从存储库开始创建异步任务。首先,我需要将旧类别和新类别捆绑在一起,以便在存储库中创建一个类。
private static class ParamsSend {
String newCategory;
String oldCategory;
ParamsSend(String newCategory,String oldCategory) {
this.newCategory = newCategory;
this.oldCategory = oldCategory;
}
}
然后我将创建一个传递这些参数的异步任务。
私有静态类 UpdateColumnAsyncTask 扩展了 AsyncTask
private UpdateColumnAsyncTask(BudgetDao budgetDao) {
this.budgetDao = budgetDao;
}
@Override
protected Void doInBackground(ParamsSend... paramsSends) {
String newCategory = paramsSends[0].newCategory;
String oldCategory = paramsSends[0].oldCategory;
budgetDao.updateColumn(newCategory,oldCategory);
return null;
}
}
然后创建调用异步任务的方法:
public void updateColumn(String newCategory,String oldCategory) {
ParamsSend paramsSend = new ParamsSend(newCategory,oldCategory);
new UpdateColumnAsyncTask(budgetDao).execute(paramsSend);
}
然后我们将转到 ViewModel 并创建一个方法来运行 Repoository 中的 Async Task:
public void updateColumn(String newCategory,String oldCategory) {
budgetRepository.updateColumn(newCategory,oldCategory);
最后,我们将在我们的活动中更新它:
budgetViewModel.updateColumn(updatedCategory,oldCategory);
祝大家好运,希望能帮到大家! :-)