Answer the question
In order to leave comments, you need to log in
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?
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)
}
}
Answer the question
In order to leave comments, you need to log in
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 questionAsk a Question
731 491 924 answers to any question