我有一个服务,提供大多数时间用户可见的UI.
当我遇到问题时,我正在尝试新的应用程序架构.
MyModelviewModel viewModel = ViewModelProviders.of(this).get(MyModelviewModel.class);
但正如你所知,this只能AppCompat或Fragment
还有其他选择吗?或者我可以将观察者直接放在我LiveData喜欢的东西上ViewModel
viewModel.getList().observe(Playground.this, new Observer<List<TestEntity>>() {
@Override
public void onChanged(@Nullable List<TestEntity> items) {
recyclerViewAdapter.addItems(items);
}
});
Run Code Online (Sandbox Code Playgroud) 我要离开这个 stackoverflow 答案/sf/answers/2437229581/将数据对象绑定到自定义视图。但是,在一切都设置好之后,我的视图没有被数据更新,而是TextView保持空白。这是我的代码(简化,为了适应这里)
activity_profile.xml::
<layout xmlns...>
<data>
<variable name="viewModel" type="com.example.ProfileViewModel"/>
</data>
<com.example.MyProfileCustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:viewModel="@{viewModel}">
</layout>
Run Code Online (Sandbox Code Playgroud)
view_profile.xml:
<layout xmlns...>
<data>
<variable name="viewModel" type="com.example.ProfileViewModel"/>
</data>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewModel.name}">
</layout>
Run Code Online (Sandbox Code Playgroud)
MyProfileCustomView.kt:
class MyProfileCustomView : FrameLayout {
constructor...
private val binding: ViewProfileBinding = ViewProfileBinding.inflate(LayoutInflater.from(context), this, true)
fun setViewModel(profileViewModel: ProfileViewModel) {
binding.viewModel = profileViewModel
}
}
Run Code Online (Sandbox Code Playgroud)
ProfileViewModel.kt:
class ProfileViewModel(application: Application) : BaseViewModel(application) {
val name = MutableLiveData<String>()
init {
profileManager.profile()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(::onProfileSuccess, Timber::d)
}
fun …Run Code Online (Sandbox Code Playgroud) data-binding android android-custom-view kotlin android-viewmodel
有两个片段:ParentFragment和ChildFragment.
ChildFragment已被添加到视图中ParentFragment.
现在使用Dagger2Android有ParentFragmentModule一个方法:
@Provides
fun provideViewModel(fragment: ParentFragment, myViewModelFactory: MyViewModelFactory): MyViewModel {
return ViewModelProviders.of(fragment, myViewModelFactory).get(MyViewModelImpl::class.java)
}
Run Code Online (Sandbox Code Playgroud)
其中MyViewModelFactory,MyViewModel,MyViewModelImpl是在应用程序中创建的简单ViewModel逻辑.
并且ChildFragmentModule具有以下方法:
@Provides
fun provideViewModel(fragment: ChildFragment, myViewModelFactory: MyViewModelFactory): MyViewModel {
return ViewModelProviders.of(fragment, myViewModelFactory).get(MyViewModelImpl::class.java)
}
Run Code Online (Sandbox Code Playgroud)
这显然是创建两个单独的实例,ViewModel因为它们接收两个不同的片段实例.
我们如何使它返回相同的实例,以便可以在Parent和Child片段之间共享数据?
我试过传递ParentFragment而不是ChildFragment在ChildFragmentModule,但这导致Dagger依赖注入错误.
我正在尝试学习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 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。我想到的问题是视图模型如何在配置更改中幸存下来。我读了很多博客文章说“
它将创建一个HolderFragment以添加到您的活动或您的片段中,它是不可见的,当配置更改时,活动被破坏,但持有者片段仍然存在
这是有道理的。但我试图对此进行更多探索,并发现在支持库 27.1.0+ 中,他们已经删除了 HolderFragment 和 Description 说
弃用 ViewModelStores.of() 和它依赖 的HolderFragment ,因为它们不再需要android.googlesource 的链接。
现在的问题是他们现在如何做同样的事情?
android mvvm android-viewmodel android-architecture-components
我使用的是生命周期版本 2.2.0-rc03,发现的官方文档和文章甚至没有列出正确的类名或构造函数参数。我想我必须通过这样的事情来获取 ViewModel 实例
viewModel = ViewModelProvider(this, SavedStateViewModelFactory(requireActivity().application, savedStateRegistryOwner))
.get(SelectedTracksViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚 SavedStateRegistryOwner。
有人可以举一个简单的例子来说明如何创建保存状态的 ViewModel 实例以及在 ViewModel 中保存和恢复值的正确方法吗?
我正在使用 Koin 将 viewModel 注入片段。我的应用程序是单一活动。我只需要在 servisFragment 和 partFragment 中使用 sharedViewModel。我想在用红色标记的导航后从 Activity 中清除该 viewModel。
我怎样才能做到这一点?
注入viewModel的代码
private val servisViewModel by sharedViewModel<ServisViewModel>()
Run Code Online (Sandbox Code Playgroud)
Koin 共享视图模型
inline fun <reified T : ViewModel> Fragment.sharedViewModel(
name: String? = null,
noinline from: ViewModelStoreOwnerDefinition = { activity as
ViewModelStoreOwner },
noinline parameters: ParametersDefinition? = null
) = lazy { getSharedViewModel<T>(name, from, parameters) }
Run Code Online (Sandbox Code Playgroud)
感谢您的任何帮助。
我遵循 MVVM 模式 - 这意味着我为每个 Fragment 都有一个 ViewModel。
我使用 ViewPager2添加了两个选项卡。
我的适配器看起来像这样:
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return new MergedItemsFragment();
case 1:
return new ValidatedMergedItemsFragment();
}
return new MergedItemsFragment();
}
Run Code Online (Sandbox Code Playgroud)
选项卡正在工作。但是,我注意到我的 MergedItemsFragment 的 ViewModel 表现得很奇怪。在我添加标签之前,我像这样导航到 Fragment:
NavHostFragment.findNavController(this).navigate(R.id.action_roomFragment_to_itemsFragment);
Run Code Online (Sandbox Code Playgroud)
当我离开那个片段NavHostFragment.findNavController(this).popBackStack()然后返回到那个片段时,我会得到一个新的空 ViewModel。这是有意的。
使用新方法,我正在使用return new MergedItemsFragment(). 当我离开那个片段并稍后返回时,我得到一个包含旧数据的 ViewModel 。这是一个问题,因为旧数据不再相关,因为用户在另一个片段中选择了不同的数据。
更新 #1
我意识到他实际上将所有旧片段保存在内存中,因为多次调用相同的打印语句。它被调用的次数随着我离开并返回该屏幕的次数而增加。因此,如果我离开并返回 10 次并旋转我的设备,他实际上会执行一行 10 次。任何猜测如何以与 ViewModels 一起工作的方式使用导航组件实现 Tabs/ViewPagers?
更新 #2
我这样设置我的 ViewModel:
@Override
public …Run Code Online (Sandbox Code Playgroud) java android android-viewmodel android-architecture-navigation android-viewpager2
我想使用 saveStateHandle 将一些数据从活动直接传递到片段的视图模型。
在我的活动中我有:
navController.addOnDestinationChangedListener { controller, _, _ ->
controller.currentBackStackEntry?.savedStateHandle?.set(
"foo",
"bar"
)
}
Run Code Online (Sandbox Code Playgroud)
所以viewModel中的代码如下所示:
MyViewModel(state: SavedStateHandle) : ViewModel() {
init {
state
?.getStateFlow("foo", "")
?.onEach { /* do something */ }
?.launchIn(viewModelScope)
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,期望值bar永远不会被发出。
我已经检查了Fragment本身,数据就在那里:
val handle = findNavController().currentBackStackEntry?.savedStateHandle
handle?.getLiveData<String>("foo")?.observe(viewLifecycleOwner) {
// here it is
}
Run Code Online (Sandbox Code Playgroud)
但是是否有可能将数据直接传递到 viewModel 的 savingStateHandle ?我相信应该是这样,因为导航器以某种方式通过了。
android android-savedstate android-viewmodel android-jetpack-navigation viewmodel-savedstate
android ×9
mvvm ×3
android-architecture-components ×2
kotlin ×2
android-architecture-navigation ×1
android-mvvm ×1
dagger ×1
data-binding ×1
java ×1
koin ×1