好的,所以我有一个显示用户帐户信息的片段。
它的工作方式是它发出一个可能会或可能不会触及服务器的请求,具体取决于已经缓存的信息。
当信息可用时,片段将在其中更新其文本字段的回调。
然而,此时用户界面需要刷新,所以我想发出某种invalidate
...
除了那完全没有任何作用。
首先,我注意到this.view
return null
。因此,我不依赖于此,而是onCreateView
明确存储我创建的视图。
然后在我更新了文本字段之后,我打电话给fragmentView.postInvalidate()
... 什么都不做。
我也试过doAsync { uiThread { fragmentView.invalidate() } }
......这也无济于事。
然后我找到了这个答案并尝试了
val fragment = this
doAsync { uiThread {
activity!!.supportFragmentManager.beginTransaction().detach(fragment).commit()
activity!!.supportFragmentManager.beginTransaction().attach(fragment).commit()
}}
...这比什么都不做更糟糕,因为如果您切换到不同的片段并返回,其他两种方式至少会更新视图,而这将永远拒绝显示任何有用的信息。
所以也许我可以通过延迟调用来“作弊”,super::setUserVisibleHint
直到我更新了值......不,我不能。
不过,我能做的是,我可以通过烘烤一些东西来强制重绘 ui。这就是我目前正在做的事情。但是,这仍然不能成为解决方案。
如何获得正确的 ui 刷新?
哦,这是一个android.support.v4.app.Fragment
,我正在使用一个android.support.v4.app.FragmentStatePagerAdapter
在片段之间切换,如果这很重要的话。
完整片段代码:
class AccountFragment : Fragment() {
lateinit var fragmentView: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
super.onCreateView(inflater, container, savedInstanceState)
val view = inflater.inflate(R.layout.fragment_account, container, false)
/*for some reason [this.view] remains null when we later try to use it, so we're explicitly storing a reference*/
fragmentView = view
return view
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
if(isVisibleToUser)setAccountInformation()
super.setUserVisibleHint(isVisibleToUser)
}
private fun setAccountInformation(){
val um = DataConfig.getUserManager()
val au = um.getActiveUser()
um.getUserInfo(au, Callback(
onResponse = {when(it){
is SuccessfulAccountGetResponse -> {
val info = it.result
usernameText.text = info.name
uuidText.text = info.uuid
adminText.text = if(info.isAdmin) "YES" else "NO"
createdText.text = info.created.toString()
lastLoginText.text = info.lastLogin?.toString() ?: "-"
//now actually force the new information to show up
refreshUI()
}
else -> doAsync { uiThread{ activity?.longToast("could not get information") } }
}},
onError = {doAsync { uiThread { activity?.longToast("error: $it") } }}
))
}
/** forces a refresh, making changes visible*/
private fun refreshUI(){
/*hack: force a redraw by toasting */
doAsync { uiThread { activity?.toast("updating values") } }
//THIS does absolutely nothing: //TODO: figure out why
// fragmentView.postInvalidate()
}
}