我有一个存储库,它包含LiveData对象,并由活动和前台服务通过ViewModel使用.当我开始观察活动时,一切都按预期工作.但是,从服务中观察不会触发观察.这是我使用的代码
class MyService: LifecycleService() {
lateinit var viewModel: PlayerServiceViewModel
override fun onCreate() {
viewModel = MyViewModel(applicationContext as Application)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
viewModel.getLiveData().observe(this, Observer { data ->
// Do something with the data
})
}
}
Run Code Online (Sandbox Code Playgroud)
任何想法为什么它不起作用,我没有收到数据?
我正在使用Android架构组件.我想要的是当用户在Edittext中键入"0"并单击按钮以将Fragment替换为新的,并且如果键入任何其他内容后发布Toast错误消息.在问题是当我从新的Fragment(BlankFragment)返回并再次单击按钮并再次输入"0"并单击时,onchange()被多次调用,因此片段被多次创建
FragmentExample.class:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
manager = getActivity().getSupportFragmentManager();
viewmModel = ViewModelProviders.of(getActivity(), viewModelFactory)
.get(VModel.class);
View v = inflater.inflate(R.layout.fragment_list, container, false);
b = (Button) v.findViewById(R.id.b);
et = (EditText) v.findViewById(R.id.et);
viewmModel.observeData().observe(getActivity(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
if(s.equals("0")) {
BlankFragment fragment = (BlankFragment) manager.findFragmentByTag(DETAIL_FRAG);
if (fragment == null) {
fragment = BlankFragment.newInstance();
}
addFragmentToActivity(manager,
fragment,
R.id.root_activity_detail,
DETAIL_FRAG
);
} else {
Toast.makeText(getContext(), "Wrong text", Toast.LENGTH_SHORT).show();
}
}
});
b.setOnClickListener(new View.OnClickListener() {
@Override …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 文档中阅读了以下内容:
您可以使用 observeForever(Observer) 方法注册一个没有关联 LifecycleOwner 对象的观察者。在这种情况下,观察者被视为始终处于活动状态,因此始终会收到有关修改的通知。您可以调用 removeObserver(Observer) 方法删除这些观察者。
我正在使用 MVVM 架构模式构建一个应用程序,使用ViewModel并在我的 ViewModel 类中声明 LiveDatas。在我的 viewModel 中,我将 aobserveForever设置为 LiveData:
val password by lazy {
MutableLiveData<String>()
}
init {
initObservable()
}
private fun initObservable() {
password.observeForever {
...
}
}
Run Code Online (Sandbox Code Playgroud)
根据我从文档中的理解,每次实例化 ViewModel 的视图(使用前面的代码)被销毁时,我都应该删除观察者,对吗?但是一旦视图被销毁,观察者不应该被销毁(因为 ViewModel 实例在视图中被实例化并且也会被销毁)?
在ViewModel和之间进行通信的正确方法是什么View,Google architecture components使用LiveData视图订阅更改并相应地更新自身,但这种通信不适用于单个事件,例如显示消息、显示进度、隐藏进度等。
有一些像SingleLiveEventGoogle 示例中的hack ,但它仅适用于 1 个观察者。一些开发人员使用EventBus但我认为当项目增长时它会很快失控。
有没有方便正确的实现方式,你是如何实现的?
(也欢迎 Java 示例)
我想LiveData<List<DataClass>>在 @Composable 函数中使用 a作为我的状态源。
我不能使用新的 @Model 注释,我在这个演讲中看到链接(在 32:06)可以通过调用函数来使用 LiveData、Flow 等+observe(/* Data */)。
问题:我找不到视频中使用的函数 (+observe()) 或任何其他使用 LiveData 作为来源的方法。如何在 @Compose 函数中使用 LiveData?
项目摇篮:
buildscript {
ext.kotlin_version = '1.3.60-eap-76'
repositories {
google()
jcenter()
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0-alpha04'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Run Code Online (Sandbox Code Playgroud)
应用程序gradle:依赖项:
def lifecycle_version = "2.1.0"
def compose_version = "0.1.0-dev02"
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
androidTestImplementation "androidx.arch.core:core-testing:$lifecycle_version"
implementation "androidx.compose:compose-runtime:$compose_version"
kapt "androidx.compose:compose-compiler:$compose_version"
// Android Compose
implementation "androidx.ui:ui-layout:$compose_version"
implementation "androidx.ui:ui-foundation:$compose_version" …Run Code Online (Sandbox Code Playgroud) android android-livedata android-jetpack android-jetpack-compose
我正在使用Retrofit,实时数据.我的项目有一种情况,我必须进行网络调用.如果任何一个失败,它应该返回错误.
目前我有两个实时数据观察员来完成工作,这不是一个好方法,所以我想知道更好的方法或示例代码来处理这样的要求.
注意:我没有使用Rxjava.
查看代码基本逻辑
String id = "items/1233"; //ID which has to to be deleted
if (isCustomizedItem) {
viewModel.deleteEvent(id);
} else {
viewModel.createCustomItems();
viewModel.deleteEvent(id);
}
Run Code Online (Sandbox Code Playgroud)
Livedata观察员
viewModel.getItemDeleted().observe(this, serverResponse -> {
if (serverResponse.status == Status.SUCCESS) {
Timber.i("Successfully deleted");
}
});
viewModel.itemCreated().observe(this, serverResponse -> {
if (serverResponse.status == Status.SUCCESS) {
Timber.i("new items added");
//Again call delete for specific item
viewModel.deleteEvent(id);
}
});
Run Code Online (Sandbox Code Playgroud)
Viewmodel代码
createItems = Transformations.switchMap(eventData, (data) -> {
if (canCreateItems(data)) {
return AbsentLiveData.create();
} else {
return eventItemRepository.createItems();
}
});
deleteItem …Run Code Online (Sandbox Code Playgroud) android-livedata ×10
android ×9
android-architecture-components ×3
android-mvvm ×1
kotlin ×1
list ×1
mvvm ×1
retrofit ×1