Проблемы с сохранением порядка элементов в RecyclerView с помощью Room? - PullRequest
0 голосов
/ 17 июня 2020

Я столкнулся с другой небольшой проблемой. У меня есть Recyclerview, который позволяет вам перемещать элементы, чтобы изменить их порядок, и мой код, кажется, сохраняет порядок только иногда, а иногда он полностью меняет его при повторном открытии. Моя цель - сохранить порядок элементов и загрузить их таким же образом.

class MainActivity : AppCompatActivity() {

    lateinit var mAdapter: MyAdapter
    lateinit var db: NotesDatabase
    lateinit var dataBaseList: MutableList<NotesEntity>

    private var itemsList = mutableListOf<String>()

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

        loadApp()
    }

    private fun loadApp() {
        GlobalScope.launch {
            dataBaseSetup()

            withContext(Dispatchers.Main) {
                setUpRecycler()
            }
        }
    }

    //Database
    private fun dataBaseSetup() {
        db = Room.databaseBuilder(
            applicationContext, NotesDatabase::class.java, "notes-list.db"
        ).build()

        //Database
        GlobalScope.launch {
            dataBaseList = db.notesDao().getAllNotes() as MutableList
            Log.d("Main", "$dataBaseList")

            for (i in 0 until dataBaseList.size) {
                itemsList.add(dataBaseList[i].title)
            }
        }
    }

    override fun onStop() {
        saveOrderedList()
        super.onStop()
    }

    override fun onPause() {
        saveOrderedList()
        super.onPause()
    }

    private fun saveOrderedList() {
        GlobalScope.launch(Dispatchers.Default) {
            for (i in 0 until dataBaseList.size) {
                db.notesDao().insertAll(NotesEntity(mAdapter.dataSet[i]))
            }
        }
    }

    private fun setUpRecycler() {
        mAdapter =
            MyAdapter(itemsList)
        val mList: DragDropSwipeRecyclerView = findViewById(R.id.list)
        mList.layoutManager = LinearLayoutManager(this)
        mList.adapter = mAdapter

        mList.orientation =
            DragDropSwipeRecyclerView.ListOrientation.VERTICAL_LIST_WITH_VERTICAL_DRAGGING
        mList.disableSwipeDirection(DragDropSwipeRecyclerView.ListOrientation.DirectionFlag.RIGHT)

        val onItemSwipeListener = object : OnItemSwipeListener<String> {
            override fun onItemSwiped(
                position: Int,
                direction: OnItemSwipeListener.SwipeDirection,
                item: String
            ): Boolean {
                Log.d("Main", "Position = $position, Direction = $direction, Item = $item")

                when (direction) {
                    //Delete Item
                    OnItemSwipeListener.SwipeDirection.RIGHT_TO_LEFT -> {
                        Toast.makeText(
                            applicationContext,
                            "$item deleted",
                            Toast.LENGTH_SHORT
                        ).show()
                        //Database
                        GlobalScope.launch(Dispatchers.Default) {
                            db.notesDao().delete(NotesEntity(item))

                        }
                    }
                    //Archive Item
                    OnItemSwipeListener.SwipeDirection.LEFT_TO_RIGHT -> {
                        Toast.makeText(
                            applicationContext,
                            "$item archived",
                            Toast.LENGTH_SHORT
                        ).show()
                        //todo: add archived code here
                    }
                    else -> return false
                }
                return false
            }
        }
        mList.swipeListener = onItemSwipeListener

        // button
        fabAddItem()
    }

    private fun fabAddItem() {
        fab_add.setOnClickListener {
            Log.d("Main", "Button pressed")
            val builder = AlertDialog.Builder(this)
            val inflater = layoutInflater
            val dialogLayout = inflater.inflate(R.layout.edit_text_layout, null)
            val editText = dialogLayout.findViewById<EditText>(R.id.et_editText)

            with(builder) {
                setTitle("Add a note!")
                setPositiveButton("OK") { dialog, which ->
                    mAdapter.updateItem(editText.text.toString())

                    //Database
                    GlobalScope.launch(Dispatchers.Default) {
                        db.notesDao().insertAll(NotesEntity(editText.text.toString()))
                    }

                    Toast.makeText(
                        applicationContext,
                        "Text added successfully",
                        Toast.LENGTH_SHORT
                    ).show()
                }
                setNegativeButton("Cancel") { dialog, which ->
                    Log.d("Main", "Negative button clicked")
                }
                setView(dialogLayout)
                show()
            }
        }
    }


}

А вот адаптер, с которого я пытаюсь получить заказ. Как вы можете видеть в методе onDragFinished(), он возвращает набор данных в порядке элементов, которые в настоящее время отображаются на экране.

class MyAdapter(dataSet: MutableList<String>) :
    DragDropSwipeAdapter<String, MyAdapter.ViewHolder>(dataSet) {

    private var list: MutableList<String> = this.dataSet as MutableList<String>

    inner class ViewHolder(itemView: View) : DragDropSwipeAdapter.ViewHolder(itemView) {
        val itemText: TextView = itemView.findViewById(R.id.item_text)
        val dragIcon: ImageView = itemView.findViewById(R.id.drag_icon)

        init {
            itemView.setOnClickListener { v: View ->
                val position: Int = adapterPosition
                Log.d("MyAdapter", list[position])

                Toast.makeText(itemView.context, dataSet[position], Toast.LENGTH_SHORT).show()
            }

        }
    }

    override fun getViewHolder(itemView: View) = ViewHolder(itemView)

    override fun onBindViewHolder(item: String, viewHolder: ViewHolder, position: Int) {
        // Here we update the contents of the view holder's views to reflect the item's data
        viewHolder.itemText.text = dataSet[position]
    }

    override fun getViewToTouchToStartDraggingItem(
        item: String,
        viewHolder: ViewHolder,
        position: Int
    ): View? {
        // We return the view holder's view on which the user has to touch to drag the item
        return viewHolder.dragIcon
    }

    override fun onDragFinished(item: String, viewHolder: ViewHolder) {
        super.onDragFinished(item, viewHolder)
        Log.d("MyAdapter", "$dataSet")

    }

    fun updateItem(item: String) {
        list.add(0, item)
        notifyItemInserted(0)

        Log.d("MyAdapter", "$list")
    }
}
...