КАК вы аннулируете вид фрагмента?
Хорошо, у меня есть фрагмент, который отображает информацию об учетной записи пользователя.
Это работает так, что он выдает запрос, который может или не может коснуться сервера, в зависимости от того, какая информация уже кэширована.
Когда информация доступна, выполняется обратный вызов, при котором фрагмент обновляет свои текстовые поля.
Однако на этом этапе пользовательский интерфейс необходимо обновить, поэтому я хотел бы выпустить invalidate
...
За исключением того, что совершенно ничего не делает.
Во-первых, я заметил, что this.view
возвращается 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
пока я не обновлю значения... нет, не могу.
Что я могу сделать, так это то, что могу перерисовать пользовательский интерфейс, поджаривая что-то. Вот чем я сейчас занимаюсь. Но тем не менее, это не может быть решением.
Как получить правильное обновление интерфейса?
Ох, и это 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()
}
}