Как вызвать notifyDatasetChanged для адаптера с вкладками? - PullRequest
0 голосов
/ 01 апреля 2020

Я использую OkHttpClient для заполнения 3 вкладок FragmentStatePagerAdapter (я знаю, не рекомендуется), который работает, но когда я изменяю данные в другом действии и возвращаюсь в MainActivity, RecyclerView не обновляется, несмотря на попытки вызывайте notifyDataSetChanged () везде, где только можно придумать. Этот вопрос в различных формах задавался бесчисленное количество раз, но ни один из ответов не получил меня нигде.

Моя основная активность:

    private lateinit var viewPager: ViewPager
    private var InventoryItems: MutableList<MutableList<String>> = ArrayList()

    class MainActivity() : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            viewPager = findViewById(R.id.view_pager)

            callServer()
        }

        private fun callServer(){
            ...
                        override fun onResponse(call: Call, response: Response){
                    response.use {
                        if (!response.isSuccessful) throw IOException("Unexpected code $response")
                        val resp = response.body!!.string()
                        this@MainActivity.runOnUiThread(Runnable {
                            parseJsonStr(resp)//loads InventoryItems array from Json response
                                //logging server response shows data in array is changed
                            setTabs()
                        })
                    }
                }
        }

        private fun setTabs(){
            pagerAdapter = SectionsPagerAdapter(supportFragmentManager, InventoryItems, this@MainActivity)
            viewPager.adapter = pagerAdapter
            val tabs: TabLayout = findViewById(R.id.tabs)
            tabs.setupWithViewPager(viewPager)
            pagerAdapter.notifyDataSetChanged()//(...doesn't work here, or at the top of this function)
        }
    }

SectionsPagerAdapter:

    private var InventoryTab1: MutableList<MutableList<String>> = ArrayList()//and same for Tab 2 and 3

    class SectionsPagerAdapter(
        fm: FragmentManager,
        private val invItems: MutableList<MutableList<String>>,
        private val context: Context
    ): FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
        override fun getItem(position: Int): Fragment {
            ...//load tab arrays from invItems
            return when (position) {
                0 -> FirstFragment(InventoryTab1)
                1 -> SecondFragment(InventoryTab2)
                else -> ThirdFragment(InventoryTab3)
            }
        }
        override fun getItemPosition(`object`: Any): Int {
            return POSITION_NONE//tried this because of some SO answers
        }
    }

... и фрагмент:

        private lateinit var rootView: View
        private lateinit var recyclerView: RecyclerView
    class FirstFragment(private val items: MutableList<MutableList<String>>) : Fragment() {
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            rootView = inflater.inflate(R.layout.fragment_first, container, false)
            recyclerView = rootView.findViewById(R.id.bk_rv)
            recyclerView.layoutManager = LinearLayoutManager(activity)
        fun clickListener(position: Int) {
            //intent to start other activity that changes server data
            startActivity(intent)
        }
        val listener = { i: Int -> clickListener(i) }
        val inventoryAdapter = activity?.let { InventoryAdapter( items, it, listener ) }
        recyclerView.adapter = inventoryAdapter
        recyclerView.adapter?.notifyDataSetChanged()//(...doesn't work here either)

        return rootView
    }

Я пытался поместить notifyDataSetChanged () на адаптер в нескольких местах, но безрезультатно. Регистрация исходного массива показывает, что данные изменяются в MainActivity, но это не передается фрагментам.

Любые предложения приветствуются!

1 Ответ

0 голосов
/ 01 апреля 2020

Наконец-то решил это с помощью

startActivityForResult(intent, 1)

в моем фрагменте (множество вопросов по SO обращено к этому, хороший учебник по по этой ссылке ); затем

    val intent = Intent()
    intent.putExtra("index", rowNumStr)
    intent.putExtra("newValue", newValueStr)
    setResult(Activity.RESULT_OK, intent)
    finish()

в действии, которое отправило изменение на сервер; и обратно во фрагмент:

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 1) {
            if (resultCode == Activity.RESULT_OK) {
                val indexStr = data?.getStringExtra("index")
                val valueStr = data?.getStringExtra("newValue")
                items[indexStr!!.toInt()][5] = valueStr.toString()
                recyclerView.adapter?.notifyDataSetChanged()
            }
        }
    }

Надеюсь, это кому-нибудь поможет!

...