2

PROBLEM - After a note is deleted from second activity, on returning back to first activity(this activity displays notes), changed made to note i.e deleted or edited does not shows change UNLESS the app is restarted and onCreate() method is recalled. If I change my device orientation, then the data gets updated.

How my code works - Basically, my app consists of two activities. First(Main) Activity is where recyclerview resides, this activity handles display of notes by fetching data from SQLite database and displays in form of cardViews. Those cardViews are click able, each cardView when clicked takes to Second(Reference) activity and a corresponding data is loaded into that activity. Now a user has a choice to either make changes to current note or to delete it. If a user clicks on delete button, data of the corresponding note is deleted from SQLite database. On deletion, app automatically goes back to Main activity. HOWEVER, the deleted note does not appears to be deleted in the main activity not until the app is restarted and onCreate method is called.

I have gone through multiple almost similar questions on the site but they do not appear to fit my needs. I am a beginner in Android development so if you could please explain it a little would greatly help me. Thank you.

MAIN ACTIVITY

class MainActivity : AppCompatActivity() {

//START OF EX-INITIALIZATIONS



var dbHandler: PediaDatabase? = null
var adapter: PediaAdapter? = null
var layoutManager: RecyclerView.LayoutManager? = null

var list: ArrayList<UserNotes>? = ArrayList()
var listItems: ArrayList<UserNotes>? = ArrayList()

val PREFS_NAME: String = "MYPREFS"
var myPrefs: SharedPreferences? = null
var first_run: Boolean = true

val REQUEST_CODE: Int = 1

var deletedNoteID: Int = 0
var deletedNoteAdapterPos: Int = 0




//END OF EX-INITIALIZATIONS

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


    showOneTimeMessage()
    invalidateOptionsMenu()



    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        window.navigationBarColor = Color.BLACK
    }





//START OF IN-INITIALIZATIONS

    dbHandler = PediaDatabase(this)
   list = ArrayList<UserNotes>()
    listItems = ArrayList()

    adapter = PediaAdapter(this, listItems!!)
    layoutManager = LinearLayoutManager(this)


    recyclerViewID.adapter = adapter
    recyclerViewID.layoutManager = layoutManager

    //END OF IN-INITIALIZATIONS


    //DATA POPULATION STARTS HERE
    list = dbHandler!!.readAllNotes()


    for(reader in list!!.iterator())
    {
        var note = UserNotes()

        note.noteTitle = reader.noteTitle
        note.noteText = reader.noteText
        note.noteID = reader.noteID
        note.noteDate = reader.noteDate

        listItems!!.add(note)
    }

    adapter!!.notifyDataSetChanged()

    //DATA POPULATION ENDS HERE



    if(dbHandler!!.totalNotes() == 0) {
        recyclerViewID.visibility = View.GONE
    }
    else{
        recyclerViewID.visibility = View.VISIBLE
        showWhenEmptyID.visibility = View.GONE
    }


}//end onCreate


override fun onRestart() {
    super.onRestart()

    overridePendingTransition(R.anim.slide_out, R.anim.slide_in)

}



override fun onCreateOptionsMenu(menu: Menu?): Boolean {

    menuInflater.inflate(R.menu.top_menu, menu)
    val item = menu!!.findItem(R.id.delete_note_menu)
    item.setVisible(false)


    return true
    //return super.onCreateOptionsMenu(menu)
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {

    if(item!!.itemId == R.id.add_note_menu){

        var isNewNote = Intent(this, ReferenceActivity::class.java)
        isNewNote.putExtra("isNewNote", true)


        startActivityForResult(isNewNote, REQUEST_CODE)
    }


    if(item!!.itemId == R.id.delete_note_menu)
    {

        Toast.makeText(this,"DELETED", Toast.LENGTH_SHORT).show()
    }

    return super.onOptionsItemSelected(item)
}


private fun showOneTimeMessage()
{
    var data: SharedPreferences = getSharedPreferences(PREFS_NAME, 0)
    if(data.contains("isShown"))
    {
        first_run = data.getBoolean("isShown", true)
    }


    Log.d("FIRST_RUN", first_run.toString())

    if(first_run) {



        val oneTimeMsg = SweetAlertDialog(this)
        oneTimeMsg.setTitleText("Hey there!")
        oneTimeMsg.setContentText("Thank you for downloading! Please don`t forget to rate our app :)").show()

        oneTimeMsg.setConfirmClickListener(object : SweetAlertDialog.OnSweetClickListener {

            override fun onClick(sweetAlertDialog: SweetAlertDialog?) {
                oneTimeMsg.dismissWithAnimation()
            }
        }).show()


        myPrefs = getSharedPreferences(PREFS_NAME, 0)
        var editor: SharedPreferences.Editor = (myPrefs as SharedPreferences).edit()
        editor.putBoolean("isShown", false)
        editor.commit()



    }
}

REFERENCE ACTVITY

class ReferenceActivity : AppCompatActivity() {

var dbHandler: PediaDatabase? = null
var note = UserNotes()

var existingNote = UserNotes()
var noteExisted: Boolean = false

var cardID: Int = 0
var cardAdapterPos: Int? = null



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



    getSupportActionBar()!!.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
    getSupportActionBar()!!.setCustomView(R.layout.custom_toolbar);
    val dateTxtView = findViewById<View>(resources.getIdentifier("action_bar_title", "id", packageName)) as TextView



    overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        window.navigationBarColor = Color.RED





    dbHandler = PediaDatabase(this)
    var data = intent
    var isNewNote = intent


    if(isNewNote != null)
        if(isNewNote.extras.getBoolean("isNewNote") != true)
        {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)

            if(data != null)
            {

                noteExisted = true


                this.cardAdapterPos = data.extras.getInt("cardPosition")
                cardID = data.extras.getInt("cardID")


                existingNote = dbHandler!!.readNote(cardID)

                refTitleID.setText(existingNote.noteTitle, TextView.BufferType.EDITABLE)
                refTextID.setText(existingNote.noteText, TextView.BufferType.EDITABLE)
                dateTxtView.text = existingNote.noteDate.toString()
            }
        }else{
            dateTxtView.text = "New note"
        }
}//end onCreate()

override fun onStop() {
    super.onStop()


    var title: String = refTitleID.text.toString().trim()
    var text: String = refTextID.text.toString().trim()

    if(existingNote.noteText == text && existingNote.noteTitle == title)
        finish()

    if(noteExisted)
    {
        if(TextUtils.isEmpty(title))
            title = "No title"


        existingNote.noteTitle = title
        existingNote.noteText = text
        //existingNote.noteDate =


        dbHandler!!.updateNote(existingNote)


        var dataToMain = this.intent
        dataToMain.putExtra("cardID", cardID)
        dataToMain.putExtra("cardAdapterPos", cardAdapterPos)
        setResult(Activity.RESULT_OK, dataToMain)


        finish()

    }
    else
    {
        if(TextUtils.isEmpty(title) && TextUtils.isEmpty(text))
        {
            finish()
        }
        else
        {
            if(TextUtils.isEmpty(title))
                title = "No title"

            note.noteTitle = title
            note.noteText = text

            dbHandler!!.createNote(note)
            finish()

        }
    }
}


override fun onCreateOptionsMenu(menu: Menu?): Boolean {

    menuInflater.inflate(R.menu.top_menu, menu)
    val addItem: MenuItem = menu!!.findItem(R.id.add_note_menu)
    val delItem:MenuItem = menu.findItem(R.id.delete_note_menu)


    addItem.setVisible(false)
    delItem.setVisible(false)

    if(noteExisted)
        delItem.setVisible(true)

    return true
    //return super.onCreateOptionsMenu(menu)
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {

    if(item!!.itemId == R.id.delete_note_menu)
    {


        val dialogMsg = SweetAlertDialog(this, SweetAlertDialog.WARNING_TYPE)
        dialogMsg.setTitleText("Are you sure?")
        dialogMsg.setContentText("You won`t be able to recover this note!")
        dialogMsg.setConfirmText("Yes,delete it!")

        dialogMsg.setConfirmClickListener(object: SweetAlertDialog.OnSweetClickListener {

            override fun onClick(sweetAlertDialog: SweetAlertDialog?) {

                dialogMsg.dismissWithAnimation()

                dbHandler!!.deleteNote(cardID)

                var successMsg = SweetAlertDialog(sweetAlertDialog!!.context, SweetAlertDialog.SUCCESS_TYPE)
                successMsg.setTitleText("Note deleted!")
                successMsg.setContentText("So long,note").show()
                successMsg.setCancelable(false)

                //TODO Disable 'OK' button on successMsg dialogbox

                Handler().postDelayed({

                    successMsg.dismissWithAnimation()
                    finish()
                }, 1200)

            }
        }).show()





    }

    return super.onOptionsItemSelected(item)
}

}

prashant17
  • 1,520
  • 3
  • 14
  • 23
Taseer
  • 3,432
  • 3
  • 16
  • 35

2 Answers2

1

After making changes to the data in the database, the RecyclerViewAdapter needs to be given a new list of data. This should be done in onRestart(), so that once you navigate back to MainActivity from SecondActivity, the RecyclerView is populated with the updated data. Try copying the code that populates the RecyclerView and put it into onRestart(). The reason why it was only updating when onCreate() was called is because that's the only place where you do anything to the view.

Tohu
  • 151
  • 2
  • 4
0

you need to update your list items inside your adapter; not sure how it works on kotlin, but I use something like this:

after a note update call adapter.updateItens(itens);

MyAdapter extendes RecyclerView.Adapter<MyViewHolder>

private List<MyItem> elements;

MyAdapter(){
    this.elements = new ArrayList<>();
}

void updateElements(List<MyItem> itens){
    Collections.sort(itens, new SortByName());
    this.elements.clear();
    this.elements.addAll(itens);

    notifyDataSetChanged();
}

you can do even better if instead of notifyDataSetChanged(), you implement a DiffUtil;

João Carlos
  • 1,405
  • 1
  • 15
  • 21
  • I have tried to call notifyDataSetChanged() in onRestart() and onResume, still nothing happens. – Taseer Aug 15 '18 at 19:45
  • add the method to update the list in the onActivityResult then: `public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_CODE: if(resultCode == Activity.RESULT_OK){ //getData from database adapter.updateElements(newData); } break;` – João Carlos Aug 15 '18 at 20:21
  • I have tried almost the same by re-reading all data from the database in onActivityResult. I have no idea why the views updates solely rely on onCreate method. – Taseer Aug 16 '18 at 07:52