LiveData类的这两个方法有什么区别?官方文档和教程对此非常模糊.在map()方法中,第一个参数叫做source,但在switchMap()中它调用了trigger.这背后的理由是什么?
我正在尝试使用Android架构组件编写示例应用程序,但即使在尝试了几天之后我也无法使用它.它给了我以上例外.
生命周期所有者: -
public class MainActivity extends LifecycleActivity {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_user);
PostViewModel viewModel = ViewModelProviders.of(this).get(PostViewModel.class);
viewModel.loadPosts();
viewModel.getPost().observe(this, new Observer<Post>() {
@Override
public void onChanged(@Nullable Post post) {
if(post != null) {
textView.setText(post.toString());
}
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
视图模型: -
public class PostViewModel extends ViewModel {
private MediatorLiveData<Post> post;
private PostRepository postRepo;
PostViewModel() {
post = new MediatorLiveData<>();
postRepo = new PostRepository();
}
public LiveData<Post> loadPosts() {
post.addSource(postRepo.getPost(),
post -> this.post.setValue(post)
); …Run Code Online (Sandbox Code Playgroud) 我的理解LiveData是,它将触发观察者对当前状态变化的数据,而不是一系列历史状态变化的数据.
目前,我有一个MainFragment执行Room写操作的程序,用于将非删除数据更改为已删除的数据.
我也是另一个TrashFragment观察到破坏数据的人.
请考虑以下情形.
MainFragment是当前活动的片段.TrashFragment尚未创建.MainFragment添加了1个已删除的数据.MainFragment用TrashFragment.TrashFragment的观察者将首先收到onChanged0个已删除的数据TrashFragment观察者将接下来接收onChanged1个已删除的数据 我的期望是,第(6)项不应该发生.TrashFragment应该只接收最新的已删除数据,即1.
这是我的代码
public class TrashFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
noteViewModel = ViewModelProviders.of(getActivity()).get(NoteViewModel.class);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { …Run Code Online (Sandbox Code Playgroud) 我最近决定仔细研究一下Google发布的新Android架构组件,特别是将他们的ViewModel生命周期感知类用于MVVM架构和LiveData.
只要我处理单个活动或单个碎片,一切都很好.
但是,我找不到一个很好的解决方案来处理Activity切换.比如说,为了一个简短的例子,活动A有一个按钮来启动活动B.
startActivity()在哪里处理?
遵循MVVM模式,clickListener的逻辑应该在ViewModel中.但是,我们希望避免在那里引用Activity.因此,将上下文传递给ViewModel不是一种选择.
我缩小了几个似乎"没问题"的选项,但却找不到任何正确的答案"这里是怎么做的".
选项1:在ViewModel中有一个枚举,其值映射到可能的路由(ACTIVITY_B,ACTIVITY_C).将此与LiveData结合使用.活动将观察此LiveData,并且当ViewModel决定应该启动ACTIVITY_C时,它只是postValue(ACTIVITY_C).然后,Activity可以正常调用startActivity().
选项2:常规接口模式.与选项1的原理相同,但Activity将实现接口.虽然我觉得与此有点联系.
选项3:消息选项,例如Otto或类似的.ViewModel发送一个Broadcast,Activity选择它并启动它所拥有的内容.此解决方案的唯一问题是,默认情况下,您应该将该广播的注册/取消注册放在ViewModel中.所以没有帮助.
选项4:拥有一个大的路由类,在某个地方,作为单例或类似的,可以被调用以将相关路由分派给任何活动.最终通过界面?所以每个活动(或BaseActivity)都会实现
IRouting { void requestLaunchActivity(ACTIVITY_B); }
Run Code Online (Sandbox Code Playgroud)
当你的应用程序开始有很多片段/活动时,这个方法让我有点担心(因为路由类会变得很大)
就是这样了.那是我的问题.你们是怎么处理这个的?你选择了我没想过的选择吗?您认为最相关的选项是什么?为什么?推荐的Google方法是什么?
PS:没有把我带到任何地方的链接1 - Android ViewModel调用Activity方法 2 - 如何从普通的非活动java类启动活动?
是否可以使用带有DialogFragment的新导航架构组件?我是否必须创建自定义导航器?
我很乐意将它们与导航图中的新功能结合使用.
android android-architecture-components android-jetpack android-architecture-navigation
根据LiveData文档:
LiveData类具有以下优点:
...
始终是最新数据:如果生命周期再次启动(如从后端堆栈返回到启动状态的活动),它将收到最新的位置数据(如果尚未生成).
但有时候我不需要这个功能.
例如,我在ViewModel中跟随LiveData,在Activity中跟踪Observer:
//LiveData
val showDialogLiveData = MutableLiveData<String>()
//Activity
viewModel.showMessageLiveData.observe(this, android.arch.lifecycle.Observer { message ->
AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK") { _, _ -> }
.show()
})
Run Code Online (Sandbox Code Playgroud)
现在每次旋转后都会出现旧的对话框.
有没有办法在处理后清除存储的值或者根本没有使用LiveData?
尝试使用Android Studio 3 Canary 5与Architecture Components和Kotlin构建示例时会发出此警告.
谁能告诉我原因?
谢谢,Ove
编辑#1:这是Dan Lew不久前制作的一个样本
https://github.com/dlew/android-architecture-counter-sample
的build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 25
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
applicationId "net.danlew.counter"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
compile "com.android.support:recyclerview-v7:${rootProject.ext.supportLibVersion}"
compile "com.android.support:design:${rootProject.ext.supportLibVersion}"
compile "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}"
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile …Run Code Online (Sandbox Code Playgroud) android kotlin android-studio android-architecture-components
在Google最近发布的Android Architecture Components库中,我们在Transformations类中有两个静态函数.虽然map功能很直接且易于理解,但我发现很难正确理解该switchMap功能.
可以在此处找到switchMap的官方文档.
有人可以用一个实际的例子解释如何以及在哪里使用switchMap功能?
参考android.arch.lifecycle.ViewModel课程.
ViewModel限定在与其相关的UI组件的生命周期中,因此在Fragment基于应用程序的应用程序中,这将是片段生命周期.这是一件好事.
在某些情况下,人们想要ViewModel在多个片段之间共享实例.具体而言,我对许多屏幕与相同基础数据相关的情况感兴趣.
(当多个相关片段显示在同一个屏幕上时,文档提出了相似的方法,但这可以通过使用单个宿主片段来解决,如下面的答案所示.)
这在官方ViewModel文档中讨论:
ViewModels还可以用作活动的不同片段之间的通信层.每个Fragment都可以通过其Activity使用相同的密钥获取ViewModel.这允许以解耦方式在片段之间进行通信,使得它们永远不需要直接与其他片段对话.
换句话说,要在表示不同屏幕的片段之间共享信息,ViewModel应将其范围限定为Activity生命周期(并且根据Android文档,这也可以在其他共享实例中使用).
现在,在新的Jetpack导航模式中,建议使用"One Activity/Many Fragments"架构.这意味着活动在应用程序使用的整个过程中都存在.
即任何ViewModel作用于Activity生命周期的共享实例永远不会被清除 - 内存仍然在不断使用.
为了保留内存并在任何时间点使用尽可能少的内容,能够ViewModel在不再需要时清除共享实例会很好.
如何ViewModel从它ViewModelStore或持有者片段手动清除?
android android-viewmodel android-architecture-components android-jetpack
我正在使用新的Android ORM Room.我遇到了以下问题,使用带参数的ORDER BY的查询不起作用.
如果我想使用从ORDER BY的参数填充的字段,它不起作用.它只是没有任何排序.
@Query("SELECT * FROM User ORDER BY :orderBY ASC")
List<User> sortedFind(String orderBY);
Run Code Online (Sandbox Code Playgroud)
但是,当我将ORDER BY列直接放在查询中以对结果进行排序时,它会按预期工作.
@Query("SELECT * FROM User ORDER BY name ASC")
List<User> sortedFind();
Run Code Online (Sandbox Code Playgroud)
这是Android Room上的错误,还是我做错了什么?
android ×10
android-architecture-components ×10
mvvm ×2
android-architecture-navigation ×1
android-room ×1
kotlin ×1