Issue
I am creating a notes app with java, i added room database to my app and when user saves a notes it adds it to database but doesn't shows in recyclerView immediately, when i reloads the app then it shows up, how and where should i insert notifyiteminserted so that recyclerView changes immediately
I have tried onResume Method but that results in app crash. This is my MainActivity.
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static ArrayList<Notes> arrNotes;
@SuppressLint("StaticFieldLeak")
RecyclerViewAdapter adapter;
RecyclerView.LayoutManager layoutManager;
notesModelView modelView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
adapter = new RecyclerViewAdapter(this, arrNotes);
recyclerView.setAdapter(adapter);
//setting up recycler view
layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//Setting custom Toolbar
Toolbar toolbar1 = findViewById(R.id.toolbar);
setSupportActionBar(toolbar1);
//Moving from MainActivity to add_Notes Activity
Button button = findViewById(R.id.floatingActionButton);
button.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, addActivity.class);
startActivity(intent);
});
}
}
This is my add_Activity.
package com.example.keepnotes;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import java.util.Objects;
public class addActivity extends AppCompatActivity {
MainActivity mainActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
Toolbar toolbar_add = findViewById(R.id.toolbar_add_activity);
setSupportActionBar(toolbar_add);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
toolbar_add.setNavigationIcon(R.drawable.back_button);
toolbar_add.setNavigationOnClickListener(view -> onBackPressed());
EditText titleText = findViewById(R.id.add_activity_title);
EditText bodyText = findViewById(R.id.add_activity_text);
Button saveBtn = findViewById(R.id.button);
DatabaseHelper database = DatabaseHelper.getDatabase(this);
saveBtn.setOnClickListener(view -> {
String titleBody = titleText.getText().toString();
String textBody = bodyText.getText().toString();
if (titleBody.equals("") && textBody.equals("")) {
Toast.makeText(addActivity.this, "Fields can't be empty",
Toast.LENGTH_LONG).show();
} else {
database.notesDao().addNotes(new Notes(titleBody, textBody));
finish();
}
});
}
}
How can i notify adapter the changes on each item add in database.
Here is my MainActivity after update to liveData.
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static ArrayList<Notes> arrNotes;
@SuppressLint("StaticFieldLeak")
RecyclerViewAdapter adapter;
RecyclerView.LayoutManager layoutManager;
notesModelView modelView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);
modelView = new ViewModelProvider(this).get(notesModelView.class);
modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
@Override
public void onChanged(List<Notes> notes) {
arrNotes = (ArrayList<Notes>) notes;
}
});
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
adapter = new RecyclerViewAdapter(this, arrNotes);
recyclerView.setAdapter(adapter);
//setting up recycler view
layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//Setting custom Toolbar
Toolbar toolbar1 = findViewById(R.id.toolbar);
setSupportActionBar(toolbar1);
//Moving from MainActivity to add_Notes Activity
Button button = findViewById(R.id.floatingActionButton);
button.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, addActivity.class);
startActivity(intent);
});
}
}
this is Dao.
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
@Dao
public interface NotesDao {
@Query("SELECT * FROM notesTable")
List<Notes> getAllNotes();
@Query("SELECT * FROM notesTable")
LiveData<List<Notes>> findAllNotes();
@Insert
void addNotes(Notes note);
@Update
void updateNotes(Notes note);
@Delete
void deleteNotes(Notes note);
}
And here is my ViewModel
package com.example.keepnotes;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class notesModelView extends AndroidViewModel {
DatabaseHelper databaseHelper;
public notesModelView(@NonNull Application application) {
super(application);
databaseHelper = DatabaseHelper.getDatabase(application.getApplicationContext());
}
public LiveData<List<Notes>> getAllNotes() {
return databaseHelper.notesDao().findAllNotes();
}
}
Solution
observe a LiveData object as it is not a LifecycleOwner
Use observeForever()
on the LiveData, manually unregistering via removeObserver()
when appropriate (onDestroy()
of the service, if not sooner).
Bear in mind that standard service limitations apply here (e.g., services run for ~1 minute on Android 8.0+ unless they are foreground services), so it may be that you need to consider other approaches anyway. 🤞
Also you can read more in original post in here -> Link
Answered By - Milad Targholi
Answer Checked By - David Marino (JavaFixing Volunteer)