您如何使片段视图无效?

时间:2019-01-30 21:27:38

标签: android android-fragments kotlin android-view-invalidate

好的,所以我有一个显示用户帐户信息的片段。

此方法的工作方式是发出可能不接触服务器的请求,具体取决于已经缓存的信息。

信息可用时,会有一个回调,其中片段将更新其文本字段。

但是,此时需要刷新UI,所以我想发出某种invalidate ...

除了什么也做不了。

首先,我注意到this.view返回null。因此,我不依赖于此,而是将在onCreateView中创建的视图明确存储。

然后,在更新文本字段后,我叫fragmentView.postInvalidate() ......。

我也尝试过doAsync { uiThread { fragmentView.invalidate() } } ...,它也无能为力。

然后我找到了this answer并尝试了

    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()
    }
}

0 个答案:

没有答案