标签: mutablelivedata

MVVM - 自定义模型的 MutableLiveData 未通过数据绑定更新到 ViewModel,并且始终为空

概括:

当我尝试向存储库发送自定义模型时,MutableLiveData 为空。我认为这是因为 MutableLiveData 的观察者。

请读到最后。

视图模型

class LoginViewModel @Inject constructor(
        private val repository: MyRepository) : ViewModel() {


    var loginModel: MutableLiveData<LoginModel>

    init {
        loginModel = MutableLiveData<LoginModel>()
    }

    fun loadUser(): LiveData<Response<Custom<Token>>> {

        return repository.login(loginModel.value!!)
    }
}
Run Code Online (Sandbox Code Playgroud)

正如你在这里看到的,我有一个 MutableLiveData

我的LoginModel是这样的

data class LoginModel(var user : String, var password : String)
Run Code Online (Sandbox Code Playgroud)

片段是使用数据绑定和与上面的 ViewModel 绑定来定义的。

登录片段.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.app.example.view.BaseActivity">

    <data>
        <variable
            name="viewModel"
            type="com.app.example.view.login.LoginViewModel" />

    </data>

    <android.support.constraint.ConstraintLayout
        android:id="@+id/activityMain"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bg_login">

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="80dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginTop="80dp" …
Run Code Online (Sandbox Code Playgroud)

data-binding mvvm kotlin android-livedata mutablelivedata

5
推荐指数
2
解决办法
2939
查看次数

如何停止多次触发 LiveData 事件

我在我的应用程序中使用 MutableLiveData 进行基于事件的通信。我有单个活动两个片段架构。

在 ViewModel 的帮助下,我正在使用 Fragment-1 中的 LiveData 事件。但是,当我使用菜单栏将 Fragment-1 替换为 Fragment-2 并最终返回到 Fragment-1 时,再次捕获了 LiveData 的旧值。

如何避免这个问题?任何帮助/建议都非常感谢!谢谢你。

android mvvm mutablelivedata

5
推荐指数
1
解决办法
2322
查看次数

即使添加“核心测试”依赖项后,也无法在我的“jUnit”测试用例中导入 InstantTaskExecutorRule - Android 测试

我正在为我的LoginViewModel. 我想setValue()在我的MutableLiveData.

为了避免android.os.Looper 中的方法 getMainLooper 未模拟异常,我尝试在test 文件夹Rule内的 ViewModel 文件中添加以下内容。

@Rule public InstantTaskExecutorRule mInstantTaskExecutorRule = new InstantTaskExecutorRule();

为此,我添加了以下依赖项:

androidTestImplementation 'android.arch.core:core-testing:1.1.1' as dependency.
Run Code Online (Sandbox Code Playgroud)

但是,我仍然无法InstantTaskExecutorRule在我的 LoginViewModelTest 文件中导入。可能是什么问题?

尽管它被导入到androidTest文件夹中,我们在其中编写集成或 UI 测试用例!但不在我们编写 jUnit 测试用例的测试文件夹中!

先感谢您。

请参考构建。梯度文件:

apply plugin: 'com.android.application'

    android {
    compileSdkVersion 28
    defaultConfig {
    applicationId "com.test.login"
    minSdkVersion 19
    targetSdkVersion 28
    versionCode 2
    versionName "1.1"
    multiDexEnabled true
    testInstrumentationRunner 
    "android.support.test.runner.AndroidJUnitRunner"
}

dataBinding {
    enabled = true
}

testOptions {
    unitTests.returnDefaultValues …
Run Code Online (Sandbox Code Playgroud)

unit-testing viewmodel android-testing android-mvvm mutablelivedata

5
推荐指数
1
解决办法
4012
查看次数

是否可以在没有附加变量的情况下增加 mutablelivedata?

我有一个带有编辑文本和 2 个按钮的简单视图,我想让用户能够使用按钮将数量增加/减少 1,或者他可以在编辑文本小部件中手动写入数量,但该值不能小于 0 且大于10. 我正在使用带有 LiveData 和数据绑定的 MVVM 架构。目前在 ViewModel 中,我有两个变量_amount: Intamount:MutableLiveData. 我正在递增/递减_amount,然后为 MutableLiveData 分配新值。它正在工作,但我想知道是否有可能仅使用一个变量来存储数量来获得相同的结果,即amount:MutableLiveData

视图模型
class TestActivityVM : ViewModel() {

    val amount = MutableLiveData<String>()
    private var _amount = 0

    init {
        amount.value = _amount.toString()
    }

    fun increment() {
        Log.d("TestActivityVM", "The amount is being increment, current value = ${amount.value}")

        //increment amount value by 1 if amount is less than 10
        if(_amount < 10) {
            amount.value = (++_amount).toString()
        }
    }

    fun decrement() …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-livedata mutablelivedata

5
推荐指数
1
解决办法
2943
查看次数

Android 单元测试:如何模拟包含 MutableLiveData 但仅公开 LiveData 的对象?

我有一个存储库类,它使用 MutableLiveData 对象(仅公开为 LiveData),将异步 Web 查询的结果返回到 ViewModel。然后,ViewModel 使用 Transformation 将结果映射到视图观察到的另一个 MutableLiveData。

我认为我通过分离关注点来遵循此模块中推荐的架构,但我发现很难为 ViewModel 编写单元测试:

class DataRepository ( private val webservice: DataWebService ) {

    private val _exception = MutableLiveData<Exception?>(null)
    val exception : LiveData<Exception?> get() = _exception

    private val _data = MutableLiveData<List<DataItem>>()

    val data: LiveData<List<DataItem>> = _data

    private val responseListener = Response.Listener<String> {response ->
        try {
            val list = JsonReader(SearchResult.mapping).readObject(response).map {
                    //Data transformation
            }
            _exception.value = null
            _data.value = list
        } catch (ex: Exception) {
            _exception.value = ex
            _data.value = emptyList()
        } …
Run Code Online (Sandbox Code Playgroud)

junit android mockito android-livedata mutablelivedata

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

自“androidx-livedata”更新 2.3.0 以来,lint 分析期间出现意外失败

运行 lint 时发生了一个奇怪的错误。这似乎发生在androidx.lifecycle从 2.2.0 更新到 2.3.0

\n
../../src/main/java/my/project/MyService.kt: Unexpected failure during lint analysis of MyService.kt\n(this is a bug in lint or one of the libraries it depends on)\n\nMessage: org.jetbrains.uast.UastErrorType cannot be cast to com.intellij.psi.PsiClassType\n\nThe crash seems to involve the detector androidx.lifecycle.lint.NonNullableMutableLiveDataDetector.\nYou can try disabling it with something like this:\n    android {\n        lintOptions {\n            disable "NullSafeMutableLiveData"\n        }\n    }\n\nStack: ClassCastException:NonNullableMutableLiveDataDetector.visitMethodCall(NonNullableMutableLiveDataDetector.kt:103)\n\xe2\x86\x90UElementVisitor$DelegatingPsiVisitor.visitMethodCallExpression(UElementVisitor.kt:1079)\n\xe2\x86\x90UElementVisitor$DelegatingPsiVisitor.visitCallExpression(UElementVisitor.kt:1059)\n\xe2\x86\x90UCallExpression$DefaultImpls.accept(UCallExpression.kt:85)\n\xe2\x86\x90UCallExpressionEx$DefaultImpls.accept(UCallExpression.kt:-1)\n\xe2\x86\x90KotlinUSimpleReferenceExpression$KotlinAccessorCallExpression.accept(KotlinUSimpleReferenceExpression.kt:129)\n\xe2\x86\x90KotlinUSimpleReferenceExpression.visitAccessorCalls(KotlinUSimpleReferenceExpression.kt:116)\n\xe2\x86\x90KotlinUSimpleReferenceExpression.accept(KotlinUSimpleReferenceExpression.kt:83)\n\nYou can set environment variable LINT_PRINT_STACKTRACE=true to dump a full stacktrace to stdout.\nThis issue type represents a problem running lint itself. …
Run Code Online (Sandbox Code Playgroud)

android lint mutablelivedata androidx

5
推荐指数
0
解决办法
2374
查看次数

LiveData(MutableLiveData)和数据绑定上升错误(无法调用观察器方法)

我有一个使用ViewModel和MutableLiveData将实时数据绑定到我的UI的应用程序。经过几个小时的时间!并在互联网上查看所有样本,但我找不到问题的原因。

我的活动:

public class DetailActivity extends DaggerAppCompatActivity {
    ActivityStudentBinding mViewDataBinding;    
    MyModel myModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mViewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_student);
        mViewDataBinding.setLifecycleOwner(this);
        myModel = ViewModelProviders.of(this).get(MyModel.class);
        mViewDataBinding.setViewmodel(myModel);
    }
Run Code Online (Sandbox Code Playgroud)

我的模型课:

public class MyModel extends ViewModel
{
    public MutableLiveData<StudentData.Student> student = new MutableLiveData<>();

    public MyModel() {
        this.student=student;
        StudentData.Student student = new StudentData().getFirstStudent();
        this.student.setValue(student);
    }    
}
Run Code Online (Sandbox Code Playgroud)

和布局(我在这里清理了多余的代码):

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <data >
        <variable
             name="viewmodel"
            type="googlearchitecturecomponents.ferdos.com.dagger211.detail.MyModel"/>
    </data>
        <TextView               
            android:text="@{viewmodel.student.id}" />    
        <TextView
            android:text="@{viewmodel.student.family}" />    
        <TextView
            android:text="@{viewmodel.student.id}"/>    
</layout>
Run Code Online (Sandbox Code Playgroud)

在运行时和创建活动时,出现以下错误:

java.lang.RuntimeException:无法启动活动ComponentInfo {googlearchitecturecomponents.ferdos.com.dagger211 …

android viewmodel android-viewholder android-livedata mutablelivedata

4
推荐指数
1
解决办法
3593
查看次数

从Room观察LiveData会导致PagedListAdapter刷新,ViewModel也会在方向更改时刷新数据

我正在构建一个使用ArticleBoundaryCallback初始化对API的调用并将响应存储在Room中的应用。我还使用LiveData收听该表,并在PagedListAdapter中显示项目。

问题在于,每次将新数据插入到Room(Article)表中时,整个列表都会刷新。

同样,在配置更改时,似乎再次获取了整个数据(ViewModel不保留它,RecyclerView被重新创建)。

每次插入时,RecyclerView都会跳转(如果插入的是新数据,则跳转几行;如果将新数据替换为旧数据,则跳转到开头)。

整个代码在此GitHub存储库中

我的课程是:

文章:

@Entity(tableName = "article",
    indices={@Index(value="id")})public class Article {
@PrimaryKey(autoGenerate = false)
@SerializedName("_id")
@Expose
@NonNull
private String id;
@SerializedName("web_url")
@Expose
private String webUrl;
@SerializedName("snippet")
@Expose
private String snippet;
@SerializedName("print_page")
@Expose
private String printPage;
@SerializedName("source")
@Expose
private String source;
@SerializedName("multimedia")
@Expose
@Ignore
private List<Multimedium> multimedia = null;
Run Code Online (Sandbox Code Playgroud)

第DAO条:

@Dao
public interface ArticleDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
long insert(Article article);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void update(Article... repos);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertArticles(List<Article> articles);


@Delete
void delete(Article... …
Run Code Online (Sandbox Code Playgroud)

android-livedata android-viewmodel android-paging mutablelivedata

4
推荐指数
1
解决办法
626
查看次数

LiveData 转换地图功能

最近我一直在学习 LiveData 上的转换方法

我知道我们可以使用maporswitchMap方法来转换实时数据。假设我们有类似下面的 Player 数据类

data class Player(val name: String, val score: Int = 0)
Run Code Online (Sandbox Code Playgroud)

我们使用map方法将player livedata转换为playerName livedata

val player: LiveData<Player> = ...

val playerName: LiveData<String> = 
    Transformations.map(player) { it.name }
Run Code Online (Sandbox Code Playgroud)

我的问题是,在观察者函数中执行它有什么区别,因为它们都在主线程中运行?我的意思是,如果我们想获取playerName,那么我们也可以在观察者函数中获取它。为什么我们声明第二个 LiveData 实例来获取它

我从本指南中获取了示例代码:https://proandroiddev.com/livedata-transformations-4f120ac046fc

kotlin android-livedata mutablelivedata mediatorlivedata android-livedata-transformations

4
推荐指数
1
解决办法
6540
查看次数

如何使用 Single Live Event 在 Kotlin 中显示 toast

我想使用单个实时事件类来显示吐司(如标志)这是我尝试过的代码。我不想使用类似标志的 peding 。我如何解决它?

主视图模型

class MainViewModel(private val movieRepository: MovieRepository) : ViewModel() {
    val keyword = MutableLiveData<String>()
    val movieList = MutableLiveData<List<Movie>>()
    val msg = MutableLiveData<String>()
    val pending: AtomicBoolean = AtomicBoolean(false)

    fun findMovie() {
        val keywordValue = keyword.value ?: return
        pending.set(true)
        if (keywordValue.isNullOrBlank()) {
            msg.value = "emptyKeyword"
            return
        }
        movieRepository.getMovieData(keyword = keywordValue, 30,
            onSuccess = {
                if (it.items!!.isEmpty()) {
                    msg.value = "emptyResult"
                } else {
                    msg.value = "success"
                    movieList.value = it.items
                }
            },
            onFailure = {
                msg.value = "fail"
            }
        )
    } …
Run Code Online (Sandbox Code Playgroud)

android kotlin mutablelivedata

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