标签: android-architecture-components

单击按钮时的Android ViewModel LiveData更新视图

我正在学习本教程以学习ViewModel和LiveData.在我的情况下,我只是在按钮点击时生成随机字符串并尝试更新文本视图,而不是从网络获取数据.问题是当按钮单击更改数据时,textview不会更新,但只有在切换方向时才会更新.

活动类(扩展LifecycleActivity)

public class PScreen extends BaseActivity {
  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.places_screen);

final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class);
viewModel.init();

viewModel.getUser().observe(this, new Observer<User>() {
  @Override public void onChanged(@Nullable User user) {
    ((TextView) findViewById(R.id.name)).setText(user.getName());
  }
});

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
  @Override public void onClick(View v) {
    final MutableLiveData<User> data = new MutableLiveData<>();
    User user = new User();
    user.setName(String.valueOf(Math.random() * 1000));
    data.postValue(user);
    viewModel.setUser(data); // Why it does not call observe()
  }
});
  }
}
Run Code Online (Sandbox Code Playgroud)

ViewModel类

package timsina.prabin.tripoptimizer.model;

import …
Run Code Online (Sandbox Code Playgroud)

android mvvm android-architecture-components

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

为什么片段重新创建时onChange()调用了两次

我正在尝试使用新的android体系结构组件,但是一时我很困惑。

我创建了一个ViewModel类

public class BuyViewModel extends ViewModel {

private BuyRepository buyRepository;
private LiveData<Adverts> advertsLiveData;
private boolean isLoading;
private int currentPage;

@Inject
public BuyViewModel(BuyRepository buyRepository) {
    this.buyRepository = buyRepository;
}

public void init(int currentPage) {
    this.currentPage = currentPage;
    if (this.advertsLiveData != null) {
        return;
    }
    Timber.tag("logi").d("BuyViewModel > init -> ");
    advertsLiveData = buyRepository.getAdverts(currentPage);
}

public LiveData<Adverts> getAdvertsLiveData() {
    return advertsLiveData;
}
}
Run Code Online (Sandbox Code Playgroud)

在我的LifeCycleFragment中观察LiveData

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    buyViewModel = ViewModelProviders.of(this, viewModelFactory).get(BuyViewModel.class);
    buyViewModel.init(1);
    buyViewModel.getAdvertsLiveData().observe(this, adverts -> {
        Timber.tag("logi").d("BuyFragment …
Run Code Online (Sandbox Code Playgroud)

android viewmodel android-livedata android-architecture-components

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

更新数据库时,LiveData List不会更新

我目前正在重构遗留代码以使用Android架构组件,并在一种存储库模式中设置房间数据库和排球请求.因此,表示/域层要求存储库获取LiveData-Objects以观察或告诉他与服务器同步,之后删除旧的db条目并从服务器重新获取所有当前的条目.

我已经为同步部分编写了测试,所以我确信,对象会被正确获取并插入到数据库中.但是当编写一个测试来观察那个db表的条目时(并测试对象是否正确保存了所有需要在将它们放入db之前完成的)LiveData>我正在观察,不会被触发.

在下面的代码片段中,您可以假设,synchronizeFormsWithServer(...)方法可以正常工作,并且异步执行数据库操作.它包含从db中删除所有Form-Objects的操作,这些操作从服务器获取的Forms列表中不存在并插入所有新的Form-Objects.因为在测试开始时数据库是空的,所以这应该不重要

观察者未被触发的测试:

  @Test
  public void shouldSaveFormsFromServerIntoDb() throws Exception
   {
    Lifecycle lifecycle = Mockito.mock(Lifecycle.class);
    when(lifecycle.getCurrentState()).thenReturn(Lifecycle.State.RESUMED);
    LifecycleOwner owner = Mockito.mock(LifecycleOwner.class);
    when(owner.getLifecycle()).thenReturn(lifecycle);

    final CountDownLatch l = new CountDownLatch(19);

    formRepository.allForms().observe(owner, formList ->
    {
     if (formList != null && formList.isEmpty())
      {
       for (Form form : formList)
        {
         testForm(form);
         l.countDown();
        }
      }
    });

    formRepository.synchronizeFormsWithServer(owner);
    l.await(2, TimeUnit.MINUTES);
    assertEquals(0, l.getCount());
   }
Run Code Online (Sandbox Code Playgroud)

FormRepository代码:

  @Override
  public LiveData<List<Form>> allForms()
   {
    return formDatastore.getAllForms();
   }
Run Code Online (Sandbox Code Playgroud)

数据存储区:

  @Override
  public LiveData<List<Form>> getAllForms()
   {
    return database.formDao().getAllForms();
   }
Run Code Online (Sandbox Code Playgroud)

formDao代码(数据库实现了你从房间里期待它的方式):

  @Query("SELECT * FROM form")
  LiveData<List<Form>> getAllForms(); …
Run Code Online (Sandbox Code Playgroud)

android observable android-room android-livedata android-architecture-components

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

房间数据库,给定日期的SELECT*FROM表

我正在Android项目中使用Room Persistence Library,并使用日期类型转换器存储日期:

object DateConverter {
    @TypeConverter
    @JvmStatic
    fun fromTimestamp(value: Long?): Date? = if (null == value) null else Date(value)

    @TypeConverter
    @JvmStatic
    fun dateToTimestamp(date: Date?): Long? = date?.time
}
Run Code Online (Sandbox Code Playgroud)

如何使用Room DAO在给定的一天从我的桌子中选择?

sqlite android android-room android-architecture-components

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

LiveData.addSource onChanged事件未调用Android

我正在Kotlin中使用Android Archi + Retrofit + RxAndroid。从服务器获得响应时,我需要更新Data对象。但是livedata.addSource的onChanged没有调用。

我正在从Git代码获取帮助:-https: //github.com/shahbazahmed1269/AndroidGithubIssues

这是我在Kotlin中的代码:-

class LoginRepository : BaseRepository() {

fun callLoginApi(data: HashMap<String, String>): LiveData<LoginResponse> {

    val liveData: MutableLiveData<LoginResponse> = MutableLiveData<LoginResponse>()

//        val call = mApiService.getLoginUser(data)

    mApiService.getLoginUser(data)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                    { user ->
                        liveData.value = user
                        Log.e("response", user.toString())
                    },
                    { error ->
                        liveData.value = LoginResponse(error = error.localizedMessage)
                        Log.e("Error", error.message)

                    })
    return liveData
}
}


open class LoginViewModel : ViewModel() {
lateinit var loginResponse : MediatorLiveData<LoginResponse>
lateinit var loginRepo:LoginRepository;
init {
    loginResponse = MediatorLiveData<LoginResponse>()
    loginRepo = LoginRepository() …
Run Code Online (Sandbox Code Playgroud)

android kotlin rx-android android-architecture android-architecture-components

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

将Room数据库公开给其他应用

Android Architectural组件引入了新概念以将应用程序数据本地存储:Room。

以前使用a ContentProvider可以将数据库公开给其他应用程序。如何处理Room?

android android-room android-livedata android-architecture-components

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

在顶部添加新项后,Recycler视图未滚动到顶部,因为尚未对列表适配器进行更改

我在实时数据的开头获取了包含新项的新列表,然后使用其数据更新适配器

viewModel.myLiveData.observe { this, Observer { myList -> 
        adapter.submitList(myList) 
        recyclerView.scrollToPosition(0)
}
Run Code Online (Sandbox Code Playgroud)

android kotlin android-recyclerview android-architecture-components

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

房间类型地图转换器

您将如何编写Map的TypeConverter?我的方法是由Moshi来做

class Converters() {

    val moshi = Moshi
            .Builder()
            .add(KotlinJsonAdapterFactory())
            .build()

    val mapOfStringsType = Types.newParameterizedType(Map::class.java, String::class.java, String::class.java)
    val mapOfStringsAdapter = moshi.adapter<Map<String, String>>(mapOfStringsType)


    @TypeConverter
    fun stringToMap(data: String): Map<String, String> {
        return mapOfStringsAdapter.fromJson(data).orEmpty()
    }

    @TypeConverter
    fun mapToString(map: Map<String, String>): String {
        return mapOfStringsAdapter.toJson(map)
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,它闻起来是因为我无法通过Converters()构造函数注入Moshi 。而且,恐怕也不是最好的表现。

android android-room android-architecture-components android-jetpack

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

为什么私有集对MutableLiveData不起作用?

我有一个密码

var exampleData = MutableLiveData<String>()
    private set
Run Code Online (Sandbox Code Playgroud)

我想将设置器隐藏为MutableLiveData的值

    exampleData.value = "Hi!" // still working
Run Code Online (Sandbox Code Playgroud)

我尝试了几种方法,但是所有方法都在工作!

var exampleData = MutableLiveData<String>()
    private set(value) { field = value } // Working!

var exampleData = MutableLiveData<String>()
    internal set // Working!

var exampleData = MutableLiveData<String>()
    internal set(value) { field = value } // Working!
Run Code Online (Sandbox Code Playgroud)

如何隐藏此二传手?

android kotlin android-architecture-components

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

我应该在MVVM中将多个网络请求链接到哪里?用例还是存储库?

我正在重构我们的代码库。现在,我们有一个单一存储库,用于存储网络请求并管理与RxJava和Kotlin Coroutines链接的运营商。

但是,该存储库被注入到多个ViewModel中,并且变得难以维护。

我想抽象我们的代码库并集成一些用例。据我所知,在useCase中使用单个网络请求是普遍的观点,这就是为什么我不确定如何链接网络请求的原因。

我需要使用Observable.zip和RxJava主题链接多个网络请求

以下流程是否正确?

Viewmodel调用useCase,后者从存储库创建网络请求,处理该网络请求,创建LiveData并将该LiveData转发到ViewModel,还从Repository更新主题,以便在所有网络请求完成后Repository可以发出一些数据

然后,我们的存储库仍然与我们当前的方法类似,只需要较少的代码,并且仅负责多个网络请求链接。

我希望我足够清楚。我研究了多个MVVM示例,但是它们对于具有复杂网络逻辑的实际应用似乎并不实用。

android mvvm rx-java2 android-livedata android-architecture-components

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