Как правильно инициализировать Recyclerview в Котлине с помощью сопрограмм?

Я изучаю kotlin Android с помощью Coroutines, и у меня проблема с правильным запуском RecyclerView. У меня есть функция вне метода onCreate, но я не могу передать Arraylist из этого метода в адаптер в onCreate. Как вы можете видеть в моем коде, я установил location_recycler_view.apply в функции getCities, но затем увидел: E / RecyclerView: адаптер не подключен; пропуск раскладки в логах. Как правильно установить код Recyclerview в моем случае?

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_add_location)

    addLocationViewModel = ViewModelProviders.of(this, addLocationViewModelFactory).get(AddLocationViewModel::class.java)

    window.setFlags(
        WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN)

    back_button.setOnClickListener {
        onBackPressed()
    }
    getCities()
    viewAdapter = LocationAdapter(cities, this) //in this case I can get normal list, but no list from ViewModel
    viewManager = LinearLayoutManager(this)

    deleteIcon = ContextCompat.getDrawable(this, R.drawable.ic_delete_white_24dp)!!

    location_recycler_view.apply {    //in this case I can set Recyclerview in normal way
        adapter = viewAdapter
        layoutManager = viewManager
    }


    val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
        override fun onMove(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean {
            return false
        }

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, position: Int) {
            (viewAdapter as LocationAdapter).removeItem(viewHolder)

            Log.e("ALA onSwiped", viewHolder.adapterPosition.toString())
            fun deleteLocation() = launch {
                addLocationViewModel.deleteLocation((viewAdapter as LocationAdapter).getCityAt(viewHolder.adapterPosition))
                Log.e("ALA onSwiped", viewHolder.adapterPosition.toString())
            }
        }

        override fun onChildDraw(
            c: Canvas,
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            dX: Float,
            dY: Float,
            actionState: Int,
            isCurrentlyActive: Boolean
        ) {
            val itemView = viewHolder.itemView

            val iconMargin = (itemView.height - deleteIcon.intrinsicHeight) / 2

            if (dX > 0) {
                swipeBackground.setBounds(itemView.left, itemView.top, dX.toInt(), itemView.bottom)
                deleteIcon.setBounds(itemView.left + iconMargin, itemView.top + iconMargin, itemView.left + iconMargin + deleteIcon.intrinsicWidth,
                    itemView.bottom - iconMargin)
            } else {
                swipeBackground.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
                deleteIcon.setBounds(itemView.right - iconMargin - deleteIcon.intrinsicWidth, itemView.top + iconMargin, itemView.right - iconMargin,
                    itemView.bottom - iconMargin)
            }

            swipeBackground.draw(c)

            c.save()

            if (dX > 0)
                c.clipRect(itemView.left, itemView.top, dX.toInt(), itemView.bottom)
            else
                c.clipRect(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)

            deleteIcon.draw(c)

            c.restore()

            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
        }

    }

    val itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback)
    itemTouchHelper.attachToRecyclerView(location_recycler_view)

    add_city_button.setOnClickListener {
        if (location_edit_text.text.toString().trim().isEmpty()) {
            Toast.makeText(this, "Location field is empty!", Toast.LENGTH_SHORT).show()
        }
         else {
            saveLocation()
        }
    }
}

private fun getCities() = launch(Dispatchers.Main) {
     val locationList = addLocationViewModel.locations.await()
    locationList.observe(this@AddLocationActivity, Observer {
        locationList -> viewAdapter = LocationAdapter(locationList as ArrayList<Location>, this@AddLocationActivity)
        location_recycler_view.apply {
            adapter = viewAdapter       //if I'm using this RV works, but I see error in logs
            layoutManager = viewManager
        }
    })
}

person beginner992    schedule 28.07.2019    source источник
comment
Вы можете заглянуть в этот репозиторий GitHub для получения надлежащей справки по использованию ко-подпрограмм Kotlin в MVVM: github.com/yash786agg / Dagger2Kotlin   -  person yash786    schedule 28.07.2019


Ответы (1)


Кажется, вам нужно инициализировать свой LocationAdapter пустым списком в методе onCreate, а затем в методе getCities вы должны установить список городов для адаптера следующим образом:

viewAdapter.cities = locationList
viewAdapter.notifyDataSetChanged()
person Andrei Tanana    schedule 29.07.2019
comment
Проблема заключалась в запуске адаптера. Я перестраиваю свой код в адаптере и действии. @ yash786 решил мою проблему. Спасибо за попытку помочь. - person beginner992; 29.07.2019