简体   繁体   English

Kotlin Android-从Fragment中的AsyncTask更新UI

[英]Kotlin Android - Update UI from AsyncTask in Fragment

I have a fragment with AsyncTask() . 我有一个与AsyncTask()的片段。 This AsyncTask() load the data from SharedPreferences and then put them in ArrayAdapter . AsyncTask()SharedPreferences加载数据,然后将其放入ArrayAdapter

The problem is, this ArrayAdapter should be used for a ListView , but from the AsyncTask() class I can't intercat with UI, because I should use a LayoutInflater in order to do it and my inflated layout is returned from the function OnCreateView so I can't pass it to AsyncTask() 问题是,此ArrayAdapter应该用于ListView ,但是从AsyncTask()类中,我无法与UI交互,因为我应该使用LayoutInflater来进行此操作,并且我的展开式布局是从函数OnCreateView返回的,因此我无法将其传递给AsyncTask()

I've tried inflating layout directly to AsyncTask() and it works, but I can't click on ListView items. 我尝试将布局直接AsyncTask()AsyncTask()并可以使用,但是我无法单击ListView项。

Tried also with 也尝试过

 if(AsyncTask.status == Status.FINISHED){
   //my code
}

but nothing happens. 但什么也没发生。

This is my OnCreateView() : 这是我的OnCreateView()

override fun onCreateView(


      inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?

    ): View? {

        val mainView = inflater.inflate(R.layout.fragment_email, container, false)

        MyAsyncTask().execute()

        if(MyAsyncTask().status == Status.FINISHED){
            mainView.email_listView.adapter = adapter

            adapter.notifyDataSetChanged()

            if(adapter.isEmpty)
                mainView.email_blank_textView.text = resources.getString(R.string.noEmail)

            mainView.email_listView.setOnItemClickListener { adapterView, _, i,  l ->
                viewEmailAlertDialog(adapterView, i, adapter)
           }

        }

This is my AsyncTask() : 这是我的AsyncTask()

inner class MyAsyncTask : AsyncTask<Unit, Unit, String>(){
    override fun doInBackground(vararg params: Unit): String {
        loadData()
        loadDataCount()

        return "FINISHED"
    }
    override fun onPostExecute(result: String) {
        if(AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES)
            adapter = ArrayAdapter(activity!!.applicationContext, R.layout.listview_text_dark, emailAddresses)
        else
            adapter = ArrayAdapter(activity!!.applicationContext, R.layout.listview_text_light, emailAddresses)

        adapter.notifyDataSetChanged()
    }
}


    return mainView
}

You are calling if(MyAsyncTask().status == Status.FINISHED) right after executing async which may not have even started working yet, 您在执行可能尚未开始工作的异步之后if(MyAsyncTask().status == Status.FINISHED)调用if(MyAsyncTask().status == Status.FINISHED)

You can feed empty list to adapter in oncreate and setonclicklistener to listview (remove async == finished logic), then just update that list and call adapter.notifyDataSetChanged on postexecute, 您可以在oncreate中将空列表提供给适配器,并在列表视图中将setonclicklistener提供给listview(删除异步==完成的逻辑),然后只需更新该列表并在后执行时调用adapter.notifyDataSetChanged,

However, i do agree with @Pawel that you shoul use coroutines, refer to my question: 但是,我同意@Pawel的意见,即您应该使用协程,请参阅我的问题:

kotlin coroutines 科特琳·协程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM