当切换回第一个选项卡时,我需要注意
不要再次返回数据!我做错了什么?你能帮帮我吗?
附言。对于导航,我使用navigation-advanced-sample中的sample,在切换选项卡后,不调用ondestroy
。
文章中的第一个解决方案是在片段中观察ViewModel中的LiveData:
一个合适的解决方案是使用getViewLifeCycleOwner()作为LifeCycleOwer,同时观察onActivityCreated中的LiveData,如下所示。
我使用以下代码,但对我不起作用:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Timber.d("onActivityCreated")
viewModel.getProfileLive().observe(viewLifecycleOwner, observer)
}
class ProfileFragment : DaggerFragment() {
@Inject
lateinit var viewModel: ProfileFragmentViewModel
private val observer = Observer<Resource<Profile>> {
when (it.status) {
Resource.Status.LOADING -> {
Timber.i("Loading...")
}
Resource.Status.SUCCESS -> {
Timber.i("Success: %s", it.data)
}
Resource.Status.ERROR -> {
Timber.i("Error: %s", it.message)
}
}
};
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Timber.d("onCreate")
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Timber.d("onCreateView")
return inflater.inflate(R.layout.fragment_profile, container, false)
}
fun <T> LiveData<T>.reObserve(owner: LifecycleOwner, observer: Observer<T>) {
removeObserver(observer)
observe(owner, observer)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Timber.d("onViewCreated")
viewModel.getProfileLive().observe(viewLifecycleOwner, observer)
// viewModel.getProfileLive().reObserve(viewLifecycleOwner, observer)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Timber.d("onActivityCreated")
}
override fun onDestroyView() {
super.onDestroyView()
Timber.d("onDestroyView")
// viewModel.getProfileLive().removeObserver(observer)
}
override fun onDestroy() {
super.onDestroy()
Timber.d("onDestroy")
}
override fun onDetach() {
super.onDetach()
Timber.d("onDetach")
}
}
class ProfileFragmentViewModel @Inject constructor(
private val profileUseCase: ProfileUseCase
) : ViewModel() {
init {
Timber.d("Init profile VM")
}
fun getProfileLive() = profileUseCase.getProfile()
}
class ProfileUseCase @Inject constructor(
private val profileRepository: ProfileRepository
) {
fun getProfile(): LiveData<Resource<Profile>> {
return profileRepository.getProfile()
}
}
profilerepository.kt类ProfileRepository@inject构造函数(私有val LoginUserDao:LoginUserDao,私有val ProfileDao:ProfileDao,){
fun getProfile(): LiveData<Resource<Profile>> =
liveData(Dispatchers.IO)
{
emit(Resource.loading(data = null))
val profile = profileDao.getProfile()
// Emit Success result...
}
}
这是因为碎片生命周期是如何工作的。当您来回移动一个片段时,onviewCreate()
再次被调用。在onviewcreated
中,调用viewmodel.getprofilelive()
,从存储库返回livedata并对其进行观察。
因为每次移动回片段时都会调用onviewcreated()
,所以对viewmodel.getprofilelive()
的调用也是如此,然后再次调用存储库,这再次触发片段中的Observe
方法。
为了解决这个问题,在ViewModel中创建一个LiveData变量,将其设置为从存储库返回的Live Data。在这个片段中,观察ViewModel的LiveData变量,而不是从存储库返回的那个变量。这样,您的Observe
方法将在第一次触发,并且仅当来自存储库的数据值发生变化时触发。
我有一个动作和一个碎片。活动没有膨胀的菜单,而片段有一个带有两个按钮的菜单。片段菜单是可见的,但按钮没有任何反应时,轻点。在调试过程中,我可以看到Fragment和Activity的onCreateOptionsMenu()都被调用,但是当点击按钮时,没有onOptionsItemSelected()被调用,既没有从Activity调用,也没有从Fragment调用。
问题内容: Ajax使用回调,因为它是同步的。 我希望对远程URL块的调用直到出现一些答案为止 ,就像在Ajax中一样,但是没有异步部分,或者我要说要进行JAX调用。 是否有任何技术可以使以下事情发生(使用JQuery)(…使用JQuery或其他解决方案): 我只是想知道-想学习。 实际上,有时会阻塞直到回复合适为止。我并不是说要浏览器阻止,而只是脚本运行时。 问题答案: 您可以在使用jQuery
我读过很多关于这方面的文章,但也有2012年或更早的文章。 (我只是打算从数据库中读取和插入一些数据。)
有没有办法阻止用户留下一个片段(点击后退按钮,从导航中导航到其他片段,等等)? 情况是,当用户点击将文件备份到USB设备时,备份过程开始(线程),如果他留下这个片段,备份过程会发生一些尴尬的事情,应用程序会崩溃。 我在想我是否可以使用一些生命周期回调,比如: 或 有没有其他方法来处理这种情况并提供最好的用户体验(可能是一些对话片段)?
由于不推荐使用TabActivity,我需要找到一种方法来使用片段。在我知道它如何工作之前,我已经使用了碎片,但我需要一个指南来创建我的标签主机与碎片活动。我在互联网上找到了几个例子,它们都是关于将片段放入标签的容器中的。
我们使用的是片段,我们不需要在重新创建活动时自动恢复它们。但是,Android每次调用->时,都会恢复片段,即使我们对这些片段使用setRetaInstance(false)。 附言。我们知道,在为配置更改重新创建活动的情况下,可以通过在manifest中添加来完成。但是,在自动清理内存的情况下,如何重新创建活动呢?