@Koshkasobaka

Почему не сохраняются данные в базу данных (SQLite)?

Подскажите, пожалуйста, что я делаю не так? Когда выхожу их приложения и захожу снова то RecyclerView пустой, данные почему-то не сохраняются. И база данных не отображается в database inspector, это значит она даже не создается?

Фрагмент, который работает с базой данных
class NotesFragment() : Fragment(), NoteAdapter.ShowDetail {
    private var binding: FragmentNotesBinding? = null
    private var adapter = NoteAdapter(this, ArrayList<Note>())
    private val dbManager = context?.let { DbManager(it) }

    interface OpenFragment {

        fun openDetailFragment(note: Note, position: Int) {}
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentNotesBinding.inflate(layoutInflater)
        return binding?.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding!!.rcList.layoutManager = GridLayoutManager(context, 2)
        binding!!.rcList.adapter = adapter

        binding!!.fbAdd.setOnClickListener {
            val newNote = Note("", "", "", true)
            (activity as OpenFragment).openDetailFragment(newNote, 0)
        }
    }

    override fun onResume() {
        super.onResume()
        dbManager?.openDb()
        fillAdapter()
        setFragmentResultListener(Constants.SAVE_EDIT) { key, bundle ->
            val title = bundle.getString(Constants.TITLE_FOR_NOTE).toString()
            val content = bundle.getString(Constants.EDIT_FOR_NOTE).toString()
            val position = bundle.getInt(Constants.POSITION_FOR_NOTE)
            val isNew = bundle.getBoolean("h")

            val note = Note(title, content, "", isNew)
            if (note.isNew) {
                adapter.addNote(note)
            } else {
                adapter.editNote(note, position)
            }
        }
    }


    override fun onClickElement(note: Note, position: Int) {
        (activity as OpenFragment).openDetailFragment(note, position)
    }

    override fun onDestroy() {
        super.onDestroy()
        dbManager!!.closeDb()
        binding = null
    }

    fun fillAdapter() {
        dbManager?.readDbData()?.let { adapter.updateAdapter(it) }
    }
}


Адаптер
class NoteAdapter(_showDetail: ShowDetail, list: ArrayList<Note>) : RecyclerView.Adapter<NoteAdapter.NoteHolder>() {
    private val noteList = list
    private val showDetail = _showDetail

    interface ShowDetail {
        fun onClickElement(note: Note, position: Int)
    }

    class NoteHolder(item: View) : RecyclerView.ViewHolder(item) {
         val tvTitle = item.findViewById<TextView>(R.id.tvTitleNote)
        val tvContent = item.findViewById<TextView>(R.id.tvContentNote)

        fun setData(note: Note) {
            tvTitle.text = note.title
            tvContent.text = note.content
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.my_note_item, parent, false)
        return NoteHolder(view)
    }

    override fun onBindViewHolder(holder: NoteHolder, position: Int) {
        holder.setData(noteList[position])
        holder.itemView.setOnClickListener {
            val title = noteList[holder.absoluteAdapterPosition].title
            val content = noteList[holder.absoluteAdapterPosition].content
            val elementPosition = holder.absoluteAdapterPosition
            val note = Note(title, content, "", false)
            showDetail.onClickElement(note, elementPosition)
        }

    }

    override fun getItemCount(): Int {
        return noteList.size
    }

    fun addNote(note: Note) {
        note.isNew = false
        this.noteList.add(0, note)
        notifyDataSetChanged()
    }


    fun editNote(note: Note, position: Int) {
        noteList.removeAt(position)
       noteList.add(0, note)
        notifyDataSetChanged()
    }

    fun updateAdapter(listItems: List<Note>) {
        noteList.clear()
        noteList.addAll(listItems)
        notifyDataSetChanged()
    }
}


База данных
class DbManager(context: Context) {
    private val dbHelper = DbHelper(context)
    var db: SQLiteDatabase? = null

    fun openDb() {
        db = dbHelper.writableDatabase
    }

    fun insertToDb(title: String, content: String, imageUri: String) {
        val values = ContentValues().apply {
            put(DbName.COLUMN_TITLE, title)
            put(DbName.COLUMN_CONTENT, content)
            put(DbName.COLUMN_IMAGE_URI, imageUri)
        }
        db?.insert(DbName.NOTE_TABLE, null, values)
    }

    fun readDbData(): ArrayList<Note> {
        val dataList = ArrayList<Note>()
        val cursor = db?.query(DbName.NOTE_TABLE, null, null, null, null, null, null)


        while (cursor?.moveToNext()!!) {
            val titleData = cursor.getString(cursor.getColumnIndex(DbName.COLUMN_TITLE))
            val contentData = cursor.getString(cursor.getColumnIndex(DbName.COLUMN_CONTENT))
            val imageUriData = cursor.getString(cursor.getColumnIndex(DbName.COLUMN_IMAGE_URI))
            dataList.add(Note(titleData, contentData, imageUriData, false))
        }
        cursor.close()
        return dataList
    }

    fun closeDb() {
        dbHelper.close()
    }
}

class DbHelper(context: Context) : SQLiteOpenHelper(context, DbName.DATABASE_NAME, null, DbName.DATABASE_VERSION){
    override fun onCreate(db: SQLiteDatabase?) {
            db?.execSQL(DbName.CREATE_TABLE)
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
       db?.execSQL(DbName.SQL_DELETE_TABLE)
        onCreate(db)
    }
}
  • Вопрос задан
  • 205 просмотров
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Android
Android developer at Yandex
Не читал всю портянку, но. Очевидно, что dbManager во фрагменте даже не создаётся. Все поля с присвоением создаются сразу при создании объекта, и в этот момент, конечно же, context == null. Читай про жизненный цикл фрагментов. Нужно отложить создание менеджера, например, использовав by lazy, или lateinit var.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы