简体   繁体   中英

Kotlin Android - Update UI from AsyncTask in Fragment

I have a fragment with AsyncTask() . This AsyncTask() load the data from SharedPreferences and then put them in 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()

I've tried inflating layout directly to AsyncTask() and it works, but I can't click on ListView items.

Tried also with

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

but nothing happens.

This is my 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() :

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,

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,

However, i do agree with @Pawel that you shoul use coroutines, refer to my question:

kotlin coroutines

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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