标签: android-livedata

Kotlin的Nullability和LiveData

我想将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

12
推荐指数
3
解决办法
4352
查看次数

实时数据被多次调用?

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)

android android-livedata

12
推荐指数
2
解决办法
3614
查看次数

刷新项目列表的MutableLiveData

我正在使用我的应用程序中的体系结构组件中的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)

android android-livedata android-architecture-components

12
推荐指数
2
解决办法
1万
查看次数

Android 中的 LiveDataScope 与 ViewModelScope

我在这里阅读了如何使用协程https://developer.android.com/topic/libraries/architecture/coroutines。是什么让我感到困惑的是之间的差异LiveDataScopeViewModelScope。听起来像是ViewModelScope自动处理生命周期,您可以在块中进行网络请求。当从服务器收到数据时,将值发布到livedata. 但是当我继续阅读时,还有另一个主题对LiveDataScope我来说似乎是多余的,因为您已经可以通过使用ViewModelScopewith来完成相同的结果livedata。这两者之间的主要区别是什么?我什么时候应该选择使用一个而不是另一个?

android android-livedata android-viewmodel kotlin-coroutines

12
推荐指数
1
解决办法
6013
查看次数

是observeForever 生命周期意识吗?

我正在使用 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

12
推荐指数
1
解决办法
6937
查看次数

如果快速调用,android LiveData Observable不会返回数据

处理需要一次性向同一端点发送多个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)

android retrofit2 android-mvvm android-livedata

11
推荐指数
1
解决办法
881
查看次数

使用自定义DataSource的分页库不会更新Room更新中的行

我一直在使用RecyclerView实现新的Paging Library,其中应用程序构建在Architecture Components之上.

填充列表的数据来自Room数据库.实际上,它是从网络中获取的,存储在本地数据库中并提供给列表.

为了提供构建列表所需的数据,我实现了自己的自定义PageKeyedDataSource.一切都按预期工作,除了一个小细节.显示列表后,如果列表行元素的数据发生任何更改,则不会自动更新.因此,例如,如果我的列表显示了具有字段名称的项目列表,并且突然,该字段在本地Room数据库中针对特定行项目更新,则列表不会自动更新行UI.

仅当使用自定义DataSource时才会发生此行为,这与通过直接返回DataSource FactoryDAO自动获取DataSource不同.但是,我需要实现自定义DataSource.

我知道可以通过调用DataSource上的invalidate()方法来重新更新列表来更新它.但是,如果应用程序一次显示2个列表(例如每个半屏),并且此项目出现在两个列表中,则需要分别为两个列表调用invalidate().

我想过一个解决方案,其中,不是使用item的类的实例来填充每个ViewHolder,而是使用它的LiveData包装版本,使每行观察其自己项目的更改并在必要时更新该行UI .不过,我看到这种方法有一些缺点:

  1. 必须将LifeCycleOwner(例如包含RecyclerView的Fragment)传递给PagedListAdapter,然后将其转发到ViewHolder以观察LiveData包装的项目.
  2. 将为每个列表的新行注册一个新的观察者,所以我根本不知道它是否有过多的计算和内存成本,考虑到它将在应用程序中的每个列表中完成,其中包含很多列表.
  3. 例如,观察LiveData包装项的LifeCycleOwner将是包含RecyclerView的Fragment,而不是ViewHolder本身,每当对该项发生更改时,即使包含该项的行不均匀,也会通知观察者.在那一刻可见,因为列表已滚动,这在我看来像浪费资源,可能会不必要地增加计算成本.

我根本不知道,即使考虑到这些缺点,它看起来似乎是一种体面的方法,或者,如果你们中的任何人知道任何其他更清洁和更好的方法来管理它.

先感谢您.

android list android-livedata android-architecture-components android-paging

11
推荐指数
1
解决办法
886
查看次数

使用ViewModel和DataBinding更新UI

我正在尝试学习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

11
推荐指数
1
解决办法
5109
查看次数

迁移到AndroidX后出现SingleLiveEvent问题

使用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)

我用谷歌搜索,找到了解决其他问题的方法,但如何优雅地解决这个问题呢?我不想在我使用单个直播活动的每个地方重构整个应用程序.

android android-studio android-livedata

11
推荐指数
1
解决办法
919
查看次数

具有多个不同类型来源的 LiveData

我目前有一个包含MyItem,并使用 Firebase/LiveData的列表的项目。它被组织成组,每个组都有项目。

如果发生以下任何情况,我希望能够更新此列表:

  1. 更新项目(在后端通过 Firebase)
  2. 过滤器已更改(每个用户在 Firebase 上都有一个单独的表格)
  3. 为项目添加了书签(每个用户在 Firebase 上都有一个单独的表格)

为了获取内容列表,我有一个像这样的函数来返回 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

11
推荐指数
1
解决办法
7695
查看次数