我正在学习本教程以学习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体系结构组件,但是一时我很困惑。
我创建了一个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
我目前正在重构遗留代码以使用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
我正在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在给定的一天从我的桌子中选择?
我正在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
Android Architectural组件引入了新概念以将应用程序数据本地存储:Room。
以前使用a ContentProvider可以将数据库公开给其他应用程序。如何处理Room?
android android-room android-livedata android-architecture-components
我在实时数据的开头获取了包含新项的新列表,然后使用其数据更新适配器
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
您将如何编写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
我有一个密码
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)
如何隐藏此二传手?
我正在重构我们的代码库。现在,我们有一个单一存储库,用于存储网络请求并管理与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
android ×10
android-architecture-components ×10
android-room ×4
kotlin ×3
mvvm ×2
observable ×1
rx-android ×1
rx-java2 ×1
sqlite ×1
viewmodel ×1