K
K
Koshkasobaka2021-07-10 16:01:06
Android
Koshkasobaka, 2021-07-10 16:01:06

Why is the data not saved to the database (SQLite)?

Tell me, please, what am I doing wrong? When I exit their applications and go back in, the RecyclerView is empty, for some reason the data is not saved. And the database doesn't show up in the database inspector, does that mean it's not even created?

Fragment that works with the database
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) }
    }
}


Adapter
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()
    }
}


Database
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)
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis Zagaevsky, 2021-07-10
@Koshkasobaka

I didn’t read the whole footcloth, but. Obviously, the dbManager is not even created in the fragment. All assignment fields are created immediately when the object is created, and at that moment, of course, context == null. Read about the life cycle of fragments. You need to postpone the creation of the manager, for example, using by lazy, or lateinit var.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question