@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)
    }
}
  • Вопрос задан
  • 228 просмотров
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Android
Android developer at Yandex
Не читал всю портянку, но. Очевидно, что dbManager во фрагменте даже не создаётся. Все поля с присвоением создаются сразу при создании объекта, и в этот момент, конечно же, context == null. Читай про жизненный цикл фрагментов. Нужно отложить создание менеджера, например, использовав by lazy, или lateinit var.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы