Update listView and Adapter after update Database - android

I have external Database and I have to update database from activity with method of update `
public long updateInfo(ModelInsertInfo modelInsertInfo)
{
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_ID,modelInsertInfo.getId());
values.put(KEY_yearWater, modelInsertInfo.getYearWater());
values.put(KEY_MonthWater, modelInsertInfo.getMonthWater());
values.put(KEY_DayWater, modelInsertInfo.getDayWater());
values.put(KEY_HourWater, modelInsertInfo.getHourWater());
values.put(KEY_MinWater, modelInsertInfo.getMinWater());
return db.update(TABLE_Insert_Info, values, "" + KEY_ID + "= " +
modelInsertInfo.getId() + "", null);
}
database updated but nothing change in list or in activity.
My Inner activity get id from click on listview item and I updated database from inner activity.
I used this
#Override
protected void onResume()
{
super.onResume();
adapterListView.notifyDataSetChanged();
listView.deferNotifyDataSetChanged();
listView.invalidateViews();
clearPref();
}
And this in the onCreate()
adapterListView.notifyDataSetChanged();
adapterListView.notifyDataSetInvalidated();
listView.invalidateViews();

Firstly I recommend using RecyclerView instead of ListView.
Secondly you may delete updating methods from onCreate() and onResume() callbacks, and just do setting updating items to RecyclerView adapter and notifyDataSetChanged. Use getter from databese after database updating for updating RecyclerView items.
RecyclerView documentation: https://developer.android.com/guide/topics/ui/layout/recyclerview

After updating database either update list by adding new value or clear list and get value from database to the list. and then give adapterListView.notifyDataSetChanged();

Related

Sequence of data from SQLite changed while displaying data in RecyclerView

I have stored data in SQLite database. I need to display that data from database in RecyclerView.But first time when Data is retrieved and displayed in RecyclerView it is retrieved in Sequence as stored in database and set on Recyclerview.When I am trying to get the same data from Database and set on RecyclerView its changing the sequence automatically.
This is code to retrieve the data from SQLite database
public ArrayList<ReservationEntry> getDbReservation(){
SQLiteDatabase db = this.getWritableDatabase();
String query="SELECT * FROM "+ RESERVATIONS;
Cursor c=db.rawQuery(query,null,null);
ArrayList<ReservationEntry> reserveList=new ArrayList<>();
if(c.moveToFirst()){
do{
ReservationEntry entry=new ReservationEntry();
entry.setName(c.getString(0));
entry.setNoOfPeople(c.getString(1));
entry.setTime(c.getString(2));
entry.setDate(c.getString(3));
entry.setBirthday(c.getString(4));
entry.setAniversary(c.getString(5));
reserveList.add(entry);
}while (c.moveToNext());
}
return reserveList;
}
This is the code to set RecyclerViewAdapter
private void readDatabaseReservation(final ArrayList<ReservationEntry> dbList) {
adapter=newReservationAdapter(dbList,getActivity().getApplicationContext());
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
How to resolve this ?
You must add your adapter this function to change data and call notifyDataSetChanged.
So add this to your adapter
public void setData(ArrayList<ReservationEntry> dbList){
this.yourListData = dbList;
notifyDataSetChanged();
}
And use it like this
private void readDatabaseReservation(final ArrayList<ReservationEntry> dbList) {
adapter.setData(dbList);
}
Hope it's help . for more add your adapter code

Refresh Recyclerview from Broadcast receiver

I have a notification which contains a next button and a previous button. Now when I press any of the buttons in the notification the actions are received by the Broadcast receiver.
What my problem is that I am having trouble refreshing my recyclerview when either of the buttons are pressed.
I have been able to do it if I would set my adapter to static in the main class and call it in the broadcast receiver it works like this:
BroadCast Receiver Class:
public void getPlaylistItems(){
if (list != null){
list.clear();
}
SongsDatabase SongsDB = new SongsDatabase(contexts);
Cursor data = SongsDB .getSongs();
if(data.getCount() != 0){
data.moveToFirst();
do{
Songs myList = new (data.getString(0), data.getString(1), data.getString(2), data.getString(3), data.getString(4));
list.add(myList);
} while (data.moveToNext());
}
data.close();
VideoDB.close();
adapter.notifyDataSetChanged <--- This was made static in my Main Activity which contains the recyclerview
}
The problem with this solution is that it causes a memory leak in my app.
Now the question is how would I be able to refresh my recyclerview without making any variables static?
I believe you are creating an inner class inside your activity/fragment. To avoid making adapter static, you can create this broadcast receiver inside on your onCreate function instead.
Other approaches could be using an Event Bus,Interfaces or RxJava.
Yes you can without having a static reference to the adapter of your RecyclerView. You have the ContentObserver for that.
As I can see that, you are fetching the songs and the videos from the local database, you can easily put a content observer along with your database table. In that case, you need to create an Uri first which might look something like this.
public static final Uri DB_TABLE_SONGS_URI = Uri
.parse("sqlite://" + Constants.ApplicationPackage + "/" + DB_TABLE_SONGS);
// DB_TABLE_SONGS refers to the database table that you have for storing songs.
Now, while updating or inserting a new row in the songs table you need to notify the content observer like this.
context.getContentResolver().notifyChange(DBConstants.DB_TABLE_SONGS_URI, null);
Now use LoaderCallbacks and LoaderManager to fetch the data from songs table. Hence, in onCreateLoader function you need to register the content observer which will aid to recycle your RecyclerView without having any static reference to it.
This is a sample onCreateLoader function.
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new SQLiteCursorLoader(getActivity()) {
#Override
public Cursor loadInBackground() {
SongsDatabase SongsDB = new SongsDatabase(contexts);
cursor = SongsDB.getSongs();
this.registerContentObserver(cursor, DBConstants.DB_TABLE_SONGS_URI);
}
return cursor;
}
};
}
Do not forget to destroy the loader instance in onDestroy function.
getLoaderManager().destroyLoader(SONGS_QUERY_LOADER);

ArrayList not updating

I try to update the ArrayList to display it in the Listview from my SQLite database but the list shows up empty. The SQLite works fine because the data shows up in the logs but is not added in the list.
One thing I want to add is that I have also linked this list with Parse to get data online and save it in my Database for offline availability.
The list updates fine when it fetches data from Parse.
public void listUpdater () {
Cursor c = myDB.rawQuery("SELECT * FROM user", null);
int titleIndex = c.getColumnIndex("title");
titles.clear();
if (c.moveToFirst()){
do {
Log.i("RESULT: ",c.getString(titleIndex));
titles.add(c.getString(titleIndex));
} while (c.moveToNext());
adapter.notifyDataSetChanged();
}
}
Here is the method call for the data
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logged_in);
myDB = openOrCreateDatabase("Users", MODE_PRIVATE, null);
myDB.execSQL("CREATE TABLE IF NOT EXISTS user(title VARCHAR)");
adapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, titles);
listView = (ListView) findViewById(R.id.listUsers);
listView.setAdapter(adapter);
listUpdater();
titles.clear();
// After this the list is updated from Parse
}
I recommend to use AsyncTask for this problem. Fetch the data from your database in doInBackground() and update the UI/list in onPostExecute().
For more information or examples check this
first of all.. why would you need to set the adapter before you fetch the data. You could do something like this.
show a loading dialog.
fetch the data from db or online/json
parse it.
initialize the adapter
set the adapter to the view.
in case you need to update the list. do a notifyItemChanged(fromPos, list.size());
hope that helps

Update the Arraylist automatically when the data of the list is updated

While inserting my listview gets refreshed automatically but not update when the item in the listview is updated. It only updates on database. I can see the listview is updated when I close the application and open again, or come back from previous activity.
I found some discussion related to my problem. Like: Refresh ListView with ArrayAdapter after editing an Item . Her I found that make a new method to populate the Listview and call it in the onResume method of your activity.
And the problem has been solved using this. But I do not get how to make new method mentioned like there. Could anybody help me to make it understandable?
My code in activity class:
personNamesListView = (ListView) findViewById(R.id.traineeslist);
traineeListAdapter = new ArrayAdapter<Trainee>(this,
android.R.layout.simple_list_item_1,
currentTraining.getTraineeArrayList());
personNamesListView.setAdapter(traineeListAdapter);
protected void onResume() {
super.onResume();
}
And this way I populated my personNamesListView using method stringToString() in model class;
public void loadTraineeList() {
DatabaseHelper db = DatabaseHelper.getInstance();
this.traineeArrayList = new ArrayList <Trainee>();
Cursor cursor = db.select("SELECT * FROM person p JOIN attendance a ON p._id = a.person_id WHERE training_id="+Integer.toString(this.getId())+";");
while (cursor.moveToNext()) {
Trainee trainee = new Trainee();
trainee.setID(cursor.getInt(cursor.getColumnIndex(DatabaseHelper.PERSON_ID)));
trainee.setFirstname(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PERSON_FIRSTNAME)));
trainee.setLastname(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PERSON_LASTNAME)));
trainee.setJobTitle(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PERSON_JOBTITLE)));
trainee.setEmail(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PERSON_EMAIL)));
trainee.setCompany(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PERSON_COMPANY)));
trainee.setDepartment(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PERSON_DEPARTMENT)));
trainee.setBadgeNumber(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PERSON_BADGE)));
// Pass to the arraylist
this.traineeArrayList.add(trainee);
}
}
public ArrayList<Trainee> getTraineeArrayList() {
return traineeArrayList;
}
public void setTraineeArrayList(ArrayList<Trainee> traineeArrayList) {
this.traineeArrayList = traineeArrayList;
}
I insert and Update data into database into one method:
public void storeToDB() {
DatabaseHelper db = DatabaseHelper.getInstance();
db.getWritableDatabase();
if (this.id == -1) {
// Person not yet stored into Db => SQL INSERT
// ContentValues class is used to store a set of values that the
// ContentResolver can process.
ContentValues contentValues = new ContentValues();
// Get values from the Person class and passing them to the
// ContentValues class
contentValues.put(DatabaseHelper.PERSON_FIRSTNAME, this
.getFirstname().trim().toUpperCase());
contentValues.put(DatabaseHelper.PERSON_LASTNAME, this
.getLastname().trim().toUpperCase());
contentValues.put(DatabaseHelper.PERSON_JOBTITLE, this
.getJobTitle().trim().toUpperCase());
contentValues.put(DatabaseHelper.PERSON_EMAIL, this.getEmail());
contentValues.put(DatabaseHelper.PERSON_COMPANY, this.getCompany()
.trim().toUpperCase());
contentValues.put(DatabaseHelper.PERSON_DEPARTMENT, this
.getDepartment().trim().toUpperCase());
contentValues.put(DatabaseHelper.PERSON_BADGE, this
.getBadgeNumber().trim().toUpperCase());
// here we insert the data we have put in values
this.setID((int) db.insert(DatabaseHelper.TABLE_PERSON,
contentValues));
} else {
// Person already existing into Db => SQL UPDATE
ContentValues updateTrainee = new ContentValues();
updateTrainee.put(DatabaseHelper.PERSON_FIRSTNAME, this
.getFirstname().trim().toUpperCase());
updateTrainee.put(DatabaseHelper.PERSON_LASTNAME, this
.getLastname().trim().toUpperCase());
updateTrainee.put(DatabaseHelper.PERSON_JOBTITLE, this
.getJobTitle().trim().toUpperCase());
updateTrainee.put(DatabaseHelper.PERSON_EMAIL, this.getEmail());
updateTrainee.put(DatabaseHelper.PERSON_COMPANY, this.getCompany()
.trim().toUpperCase());
updateTrainee.put(DatabaseHelper.PERSON_DEPARTMENT, this
.getDepartment().trim().toUpperCase());
updateTrainee.put(DatabaseHelper.PERSON_BADGE, this
.getBadgeNumber().trim().toUpperCase());
db.update(DatabaseHelper.TABLE_PERSON, updateTrainee,
DatabaseHelper.PERSON_ID+"= ?", new String[]{Integer.toString(this.getId())});
System.out.println("Data updated");
}
}
You should call traineeListAdapter.notifyDataSetChanged() whenever you update your ArrayList representing the items in the ListView.
There's a similar question here that can give you some help.
Although I've accomplished something similar using
yourlistview.invalidateViews()
after changing the data to show in the listview
when notifyDataSetChanged() didn't work.
EDIT:
After making all the operations in the data that I want to show i just set the adapter and try to refresh my listview by calling invalidateViews().
selectedStrings = new ArrayList<String>(typeFilterStrings);
adapter.setArrayResultados(selectedStrings);
listTypeFilter.invalidateViews();
It's not obligatory to set the adapter again in my case worked.
use like this:
Create an instance of your custom adapter, so you can use it anywhere you like...
public class ScoreList extends SherlockFragmentActivity {
private ListView listViewScore;
private ScoreListAdapter adapter;
static List<Score> listScore = new ArrayList<Score>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.score_list);
ctx = this;
listScore = dbh.getAllScores();
listViewScore = (ListView) findViewById(R.id.score_list);
adapter = new ScoreListAdapter(ctx, R.layout.score_row_item, listScore);
listViewScore.setAdapter(adapter);
((BaseAdapter) listViewScore.getAdapter()).notifyDataSetChanged();
}
}
By the way, if your listScore array is already loaded, then you do not need to use
adapter.notifyDatasetChanged();

How to update the parent activity's listview on child activity return

I have two activities: one NoteListActivity which inherits from ListActivity, and I used SimpleCursorAdapter as its adapter where the cursor is obtained as below:
public Cursor getAllNotesCursor() {
String selectQuery = "SELECT _id , title, content FROM " + NOTE_TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
return cursor;
}
The another activity NoteEditorActivity is responsible for creating new note, there is a save action there and on click I will add a new note in the SQLite database then call finish to the NoteListActivity.
The problem is that the NoteListActivity didn't get updated with new note, do you know the best practice to achieve this?
One solution I can thought of is starting NoteEditorActivity by calling startActivityForResults then call cursor requery in onActivityResult, I don't know whether there is better solution?
startActivityForResults is good, but why not try to override onResume() method, with yourAdapter.notifyDataChange()
#Override
public void onResume() {
...
yourAdapter.notifyDataSetChanged();
}
Of course you have to add yourAdapter on your field class.
Whatever you are doing in onCreate method that is affecting UI to draw or show note by fetching from database.
Don't do it in onCreate.
DO IT IN onResume
#Override
public void onResume(){
//fetch here, do other operation, or set layout here
}
notifyDataSetChanged Update List View Adopter
http://androidadapternotifiydatasetchanged.blogspot.in/
try following steps..
use startActivityForResult() inside NoteListActivity to start NoteEditorActivity.
set RESULT_OK in save button click event
Populate list in onActivityResult() of NoteListActivity

Categories

Resources