我想将LiveData与Kotlin一起使用,并且值不应为null.你怎么处理这个?也许LiveData的包装?在这里寻找好的模式..作为一个例子:
class NetworkDefinitionProvider : MutableLiveData<NetworkDefinition>() {
val allDefinitions = mutableListOf(RinkebyNetworkDefinition(), MainnetNetworkDefinition(), RopstenNetworkDefinition())
init {
value = allDefinitions.first()
}
fun setCurrent(value: NetworkDefinition) {
setValue(value)
}
}
Run Code Online (Sandbox Code Playgroud)
我知道访问时值不会为空 - 但我总是要检查null或者让这些丑陋!
android kotlin android-livedata android-architecture-components
我Android Architecture Components在我的应用程序中使用.在我的登录Activty中,我在登录失败时显示对话框!
由于实时数据,对话框已显示超过3次.我添加了一些日志并发现它livedata被多次调用.
我该如何解决这个问题?
活动
mViewModel.authenticate(token, binding.inputPassword.getText().toString()).observe(LoginActivity.this, apiResponse -> {
progress.dismiss();
if (apiResponse != null) {
if (apiResponse.getError() != null) {
Log.e("Login", "Network Failure");
} else {
if (apiResponse.getAuthuser().getStatus().equals("VALID")) {
PrefUtils.saveUserToPrefs(LoginActivity.this, apiResponse.getAuthuser());
finish();
} else if (apiResponse.getAuthuser().getStatus().equals("INVALID")) {
Log.e("LOGIN Issue ", "Showing Dialog" + apiResponse.getAuthuser().getStatus());
loginFailure();
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
视图模型
class LoginActivityViewModel extends ViewModel {
private final FarmerRepository farmerRepository;
private MediatorLiveData<ApiResponse> mApiResponse;
LoginActivityViewModel(FarmerRepository repository) {
mApiResponse = new MediatorLiveData<>();
farmerRepository = repository;
}
MediatorLiveData<ApiResponse> …Run Code Online (Sandbox Code Playgroud) 我正在使用我的应用程序中的体系结构组件中的LiveData和ViewModel.
我有一个分页的项目列表,我在用户向下滚动时加载更多.查询结果存储在
MutableLiveData<List<SearchResult>>
Run Code Online (Sandbox Code Playgroud)
当我执行初始加载并将变量设置为新列表时,它会在绑定适配器上触发回调,将数据加载到recyclerview中.
但是,当我加载第二页并将其他项添加到列表中时,不会触发回调.但是,如果我用包含旧项和新项的新列表替换列表,则回调会触发.
是否可以让LiveData在更新支持列表时通知其观察者,而不仅仅是在LiveData对象更新时?
这不起作用(忽略空检查):
val results = MutableLiveData<MutableList<SearchResult>>()
/* later */
results.value.addAll(newResults)
Run Code Online (Sandbox Code Playgroud)
这有效:
val results = MutableLiveData<MutableList<SearchResult>>()
/* later */
val list = mutableListOf<SearchResult>()
list.addAll(results.value)
list.addAll(newResults)
results.value = list
Run Code Online (Sandbox Code Playgroud) 我在这里阅读了如何使用协程https://developer.android.com/topic/libraries/architecture/coroutines。是什么让我感到困惑的是之间的差异LiveDataScope和ViewModelScope。听起来像是ViewModelScope自动处理生命周期,您可以在块中进行网络请求。当从服务器收到数据时,将值发布到livedata. 但是当我继续阅读时,还有另一个主题对LiveDataScope我来说似乎是多余的,因为您已经可以通过使用ViewModelScopewith来完成相同的结果livedata。这两者之间的主要区别是什么?我什么时候应该选择使用一个而不是另一个?
android android-livedata android-viewmodel kotlin-coroutines
我正在使用 MVVM,并且已经对其进行了不同的实现,但仍然让我怀疑的一件事是如何从我的 ViewModel 的存储库 (Firebase) 获取数据,而不将任何生命周期附加到 ViewModel。
我已经observeForever()从 ViewModel实现了,但我认为这不是一个好主意,因为我认为我应该通过回调或转换从我的存储库到我的 ViewModel 进行通信。
我在这里留下一个例子,我从 Firebase 获取设备并更新我的 UI,如果我们能在这里看到,我正在观察来自 UI 的 repo 的数据,但从 ViewModel 我也在观察来自 repo 的数据,这就是我真正怀疑我是否使用正确方法的地方,因为我不知道如果我的视图被破坏是否observeForever()会被清除onCleared(),所以如果视图死亡,它不会让观察者保持活动状态。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
val deviceId = editText.text.toString().trim()
observeData(deviceId)
}
}
fun observeData(deviceId:String){
viewModel.fetchDeviceData(deviceId).observe(this, Observer {
textView.text = "Tipo: ${it.devType}"
})
Run Code Online (Sandbox Code Playgroud)
class MainViewmodel: ViewModel() {
private val repo = Repo()
fun fetchDeviceData(deviceId:String):LiveData<Device>{
val mutableData = MutableLiveData<Device>()
repo.getDeviceData(deviceId).observeForever {
mutableData.value = it
}
return mutableData …Run Code Online (Sandbox Code Playgroud) android mvvm kotlin android-livedata android-architecture-components
处理需要一次性向同一端点发送多个API调用的应用程序.
例如 - 目录浏览方案,需要通过发送当前文件夹中所有文件夹的get调用来获取目录结构.问题是,响应正确地为所有文件夹提供了响应,但LiveData observable只为整个列表提供了一个响应.
目录结构: -
test -> temp -> temp1 -> temp2
-> temp3
-> temp4
Run Code Online (Sandbox Code Playgroud)
可观察到收听回调: -
mViewModel.getServerFilesLiveData().observe(this, browseServerDataResource -> {
if (browseServerDataResource != null) {
if (browseServerDataResource.status == APIClientStatus.Status.SUCCESS) {
if (browseServerDataResource.data != null) {
Timber.i("Got data for path %s in Observable", browseServerDataResource.data.path);
if (browseServerDataResource.data.folderList != null
&& browseServerDataResource.data.folderList.size() > 0) {
for (final String name : browseServerDataResource.data.folderList) {
final ServerDirectoryPathInfo pathInfo = new ServerDirectoryPathInfo();
pathInfo.completePath = browseServerDataResource.data.path + "/" + name;
getFolderDownloadPath(pathInfo.completePath);
}
}
mFolderCountToParse--; …Run Code Online (Sandbox Code Playgroud) 我一直在使用RecyclerView实现新的Paging Library,其中应用程序构建在Architecture Components之上.
填充列表的数据来自Room数据库.实际上,它是从网络中获取的,存储在本地数据库中并提供给列表.
为了提供构建列表所需的数据,我实现了自己的自定义PageKeyedDataSource.一切都按预期工作,除了一个小细节.显示列表后,如果列表行元素的数据发生任何更改,则不会自动更新.因此,例如,如果我的列表显示了具有字段名称的项目列表,并且突然,该字段在本地Room数据库中针对特定行项目更新,则列表不会自动更新行UI.
仅当使用自定义DataSource时才会发生此行为,这与通过直接返回DataSource Factory从DAO自动获取DataSource不同.但是,我需要实现自定义DataSource.
我知道可以通过调用DataSource上的invalidate()方法来重新更新列表来更新它.但是,如果应用程序一次显示2个列表(例如每个半屏),并且此项目出现在两个列表中,则需要分别为两个列表调用invalidate().
我想过一个解决方案,其中,不是使用item的类的实例来填充每个ViewHolder,而是使用它的LiveData包装版本,使每行观察其自己项目的更改并在必要时更新该行UI .不过,我看到这种方法有一些缺点:
我根本不知道,即使考虑到这些缺点,它看起来似乎是一种体面的方法,或者,如果你们中的任何人知道任何其他更清洁和更好的方法来管理它.
先感谢您.
android list android-livedata android-architecture-components android-paging
我正在尝试学习View-model android,在我学习的第一阶段我试图通过使用视图模型和数据绑定来更新UI(Textview).在View模型中,我有一个aynctask回调,它将调用REST api调用,我正在输出,但我没有更新textview中的值.
我的viewmodel类
public class ViewModelData extends ViewModel {
private MutableLiveData<UserData> users;
public LiveData<UserData> getUsers() {
if (users == null) {
users = new MutableLiveData<UserData>();
loadUsers();
}
return users;
}
public void loadUsers() {
ListTask listTask =new ListTask (taskHandler);
listTask .execute();
}
public Handler taskHandler= new Handler() {
@Override
public void handleMessage(Message msg) {
UserData userData = (UserData) msg.obj;
users.setValue(userData);
}
};
Run Code Online (Sandbox Code Playgroud)
}
和主要课程
public class MainActivity extends AppCompatActivity implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry;
private TextView fName;
@Override …Run Code Online (Sandbox Code Playgroud) android-databinding android-livedata android-viewmodel android-architecture-components
使用Android studio 3.2.1迁移到AndroidX后,由于此错误,我无法运行应用程序:
SingleLiveEvent.java:29: error: name clash: observe(LifecycleOwner,Observer<T#1>) in SingleLiveEvent and observe(LifecycleOwner,Observer<? super T#2>) in LiveData have the same erasure, yet neither overrides the other
public void observe(LifecycleOwner owner, final Observer<T> observer) {
^
where T#1,T#2 are type-variables:
T#1 extends Object declared in class SingleLiveEvent
T#2 extends Object declared in class LiveData
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索,找到了解决其他问题的方法,但如何优雅地解决这个问题呢?我不想在我使用单个直播活动的每个地方重构整个应用程序.
我目前有一个包含MyItem,并使用 Firebase/LiveData的列表的项目。它被组织成组,每个组都有项目。
如果发生以下任何情况,我希望能够更新此列表:
为了获取内容列表,我有一个像这样的函数来返回 LiveData,每当一个项目更新(#1)时它就会更新。
getList(id: String): LiveData<List<MyItem>> {
val data = MutableLiveData<List<MyItem>>()
firestore
.collection("groups")
.document(id)
.collection("items")
.addSnapshotListener { snapshot, exception ->
val items = snapshot?.toObjects(MyItem::class.java) ?: emptyList()
// filter items
data.postValue(items)
}
return data
}
Run Code Online (Sandbox Code Playgroud)
在我的 ViewModel 中,我有处理这种情况的逻辑。
private val result = MediatorLiveData<Resource<List<MyItem>>>()
private var source: LiveData<List<MyItem>>? = null
val contents: LiveData<Resource<List<MyItem>>>
get() {
val group = database.group
// if the selected group is changed.
return Transformations.switchMap(group) …Run Code Online (Sandbox Code Playgroud) android kotlin android-livedata google-cloud-firestore mutablelivedata
android-livedata ×10
android ×9
android-architecture-components ×5
kotlin ×3
android-mvvm ×1
list ×1
mvvm ×1
retrofit2 ×1