This is how my recyclerView is coded (partially):
expensesListCursor = dbc.listExpenses(selectedDate);
mLayoutManager = new LinearLayoutManager(getActivity());
rvExpenses.setLayoutManager(mLayoutManager);
rvExpenses.setItemAnimator(new DefaultItemAnimator());
mAdapter = new AdapterExpensesList(expensesListCursor,getActivity());
rvExpenses.setAdapter(mAdapter);
here's how my dbc.ListExpenses is written
public Cursor listExpenses(String date){
Cursor cursor;
cursor = database.query(MySQLiteHelper.TABLE_EXPENSES, new String[] {"rowid as _id", "description, cost"}, "date='" + date + "'", null, null, null, "_id asc");
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
and here's how AdapterExpensesList is written
public class AdapterExpensesList extends RecyclerView.Adapter<AdapterExpensesList.ViewHolder> {
Cursor myDataCursor;
public AdapterExpensesList(Cursor expensesListCursor, Context context){
myDataCursor = expensesListCursor;
}
As you can probably see above, the items in my RecyclerView is taken directly from cursor. My problem is now, I'd like to implement the feature to remove some of the data in the RecyclerView. From the examples I found on the net, usually here's how they did it:
private ArrayList<String> mDataset;
public void remove(String item) {
int position = mDataset.indexOf(item);
mDataset.remove(position);
notifyItemRemoved(position);
}
The problem is my data is a cursor object, and cursor doesn't have the .remove(position) like ArrayList for example. So how do I achieve the same thing, that is to remove certain data from certain position?
Note: I just want to remove data from particular (selected) position, and not the data inside the database itself.
You can not delete items from the cursor check it here.
https://stackoverflow.com/a/6724929/5492047
Instead you can convert your cursor items in list https://www.javatpoint.com/java-list or arraylist https://www.javatpoint.com/java-arraylist
and achieve your task.
Related
I am retrieving data from SQLite and trying to display it in the ListView. The problem is I have two columns in the database and the listview only shows data from one column. I am using following code for this purpose
public List<entry> getAllEntries() {
List<Entry> entries = new ArrayList<Entry>();
Cursor cursor = database.query(MySQLiteHelper.TABLE_ENTRIES,
allEntries, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Entry entry = cursorToEntry(cursor);
Entry entry1 = cursorToEntry(cursor);
Log.d(TAG, "get entry = " + cursorToEntry(cursor).toString());
entries.add(entry);
cursor.moveToNext();
Log.d(TAG, "get amount = "+ cursorToEntries(cursor).toString1());
entries.add(entry1);
cursor.moveToNext();
}
cursor.close();
return entries;
}
And I have also been trying following code
while(cursor.moveToNext())
{
entries.add("Entry"+cursor.getString(1)+"Amount"+cursor.getString(2));
}
And thats how I am displaying it in the ListView
List<Entry> values = datasource.getAllEntries();
ArrayAdapter<Entry> adapter = new ArrayAdapter<Entry>(this,
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
}
You can either use a CursorAdapter, which lets you specify a row layout as well as how to map from columns in the cursor to views in the layout; or you can write your own adapter implementation that extends from BaseAdapter and is internally backed by a Cursor. I suggest you watch The World of ListView.
I have a list of items in an Android activity. I want users to be able to reorder the list by clicking buttons on the list item that then update a weight value within an SQLite database. The list is populated from a CursorLoader.
I have implemented a solution that doesn't use the CursorLoader. This means that the weight value changes but doesn't refresh the CursorLoader. The list order doesn't refresh until the list activity is restarted.
This is the code in the CursorAdapter that calls the function to adjust the weight when the button is clicked.
final int rowID = cursor.getInt(cursor.getColumnIndex(Storage.COLUMN_ID));
Button upButton = (Button) view.findViewById(R.id.activity_edit_move_up);
upButton.setOnClickListener(new OnClickListener() {
public void onClick(View v){
Storage store = new Storage(v.getContext());
store.increaseActivityWeight(rowID);
}
});
This is the function in the Storage SQLiteOpenHelper class that changes the weight.
public void increaseActivityWeight(int activityID) {
SQLiteDatabase db = getReadableDatabase();
String[] d = { };
Cursor c;
c = db.rawQuery("SELECT _id, weight FROM activity WHERE _id = "+activityID, d);
if (c.moveToFirst()) {
int oldWeight = c.getInt(1);
int newWeight = oldWeight + 1;
ContentValues cvSelectedActivity = new ContentValues();
cvSelectedActivity.put("weight",Integer.toString(newWeight));
db.update(Storage.ACTIVITY_TABLE_NAME, cvSelectedActivity, "_id "+"="+activityID, null);
// EDIT: The following code is incomplete. It needs to identify a displaced activity by weight and swap it's weight with that of the old activity.
int displacedActivityID = c.getInt(0);
ContentValues cvDisplacedActivity = new ContentValues();
cvDisplacedActivity.put("weight",Integer.toString(newWeight));
db.update(Storage.ACTIVITY_TABLE_NAME, cvDisplacedActivity, "_id "+"="+displacedActivityID, null);
}
db.close();
c.close();
}
This initiates the CursorLoader and orders the list in the ListActivity.
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { Storage.COLUMN_ID, Storage.ACTIVITY_NAME, Storage.WEIGHT };
CursorLoader cursorLoader = new CursorLoader(getActivity(),
ActivityContentProvider.CONTENT_URI, projection, null, null, Storage.WEIGHT);
return cursorLoader;
}
Is there a way to access the CursorLoader within the CursorAdapter? Can I add implements
LoaderManager.LoaderCallbacks<Cursor> to the CursorAdapter?
I saw this tutorial that offers an alternative solution.
http://androidforbeginners.blogspot.it/2010/03/clicking-buttons-in-listview-row.html
I started implementing it this way but changed to the custom CursorAdapter. I can't remember why.
Any advice on this would be much appreciated.
I'm quite beginner with android and I have problem with my listview.
So I'm getting listview values from database and thats working fine. But I want to edit one of those values before showing it to user and after many failures I kindly ask your advice.
Here is my code for fetching data and showing it in listview
listSquad=(ListView)findViewById(R.id.listview);
String[] arrayColumns = new String[]{"sq_pos", "sq_name", "sq_born", "sq_gam", "sq_goal"};
int[] arrayViewID = new int[]{R.id.pos,R.id.name,R.id.age,R.id.games,R.id.goals};
DBAdapter db = new DBAdapter(this);
db.open();
Cursor c;
c = db.doQuery("squad", null, null, null, null, null, "sq_name");
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.team_list_lay, c, arrayColumns, arrayViewID);
listSquad.setAdapter(adapter);
So I would like to take value of "sq_born" column and alter it and then show up in listview. That column is integer.
Like suggested by Aditya Rai, I used viewbinder like below:
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int column) {
if( view.getId() == R.id.age){
//do something here
TextView text = (TextView)view;
//set text in here
text.setText("blaah");
return true;
}
return false;
}
});
I am new to android development and have come across a problem with deleting a row in a SQLite table that I have not been able to find a solution to. When I try to delete a row nothing is happening.
In my activity, called 'MainActivity,' I am using a context menu to call a method to delete an item from the list. This portion of code is as follows:
case R.id.delete_program:
DBAdapter adap = new DBAdapter(this);
adap.open();
long pass = (long) (position + 1);
adap.removeFromCurrent(pass);
adap.close();
Runnable run = new Runnable() {
public void run(){
refreshCurrent(getApplicationContext());
}
};
runOnUiThread(run);
proAdapt.notifyDataSetChanged();
return true;
In 'DBAdapter' the method removeFromCurrent():
public boolean removeFromCurrent(long cp_id) {
return this.dB.delete(PROGRAMS_TABLE, CP_ID + '=' + cp_id, null) > 0;
}
In 'MainActivity' the method refreshCurrent():
public static void refreshCurrent(Context context) {
CURRENT.clear();
DBAdapter adap = new DBAdapter(context);
adap.open();
ArrayList<Program> temp = adap.getCurrentPrograms();
for(Program item : temp) {
Toast.makeText(context, "Item added: " + item.getName(), Toast.LENGTH_SHORT).show();
CURRENT.add(item);
}
adap.close();
}
I'm using the toast to check if the table has changed but the display has not.
From 'DBAdapter' the method getCurrentPrograms():
public ArrayList<Program> getCurrentPrograms() {
ArrayList<Program> list = new ArrayList<Program>();
Cursor cursor =
this.dB.query(PROGRAMS_TABLE, new String[] {
CP_ID, CP_NAME, ACTUAL_DAY, D_ID, CP_CYCLE, CP_DAY_ONE },
null, null, null, null, null);
int rows = cursor.getCount();
if(cursor != null)
cursor.moveToFirst();
for(int i = 1; i <= rows; i++) {
list.add(new Program(cursor.getString(cursor.getColumnIndex(CP_NAME)),
cursor.getInt(cursor.getColumnIndex(ACTUAL_DAY)),
cursor.getInt(cursor.getColumnIndex(CP_DAY_ONE)),
cursor.getInt(cursor.getColumnIndex(CP_CYCLE))));
cursor.moveToNext();
}
return list;
}
The ArrayList 'CURRENT' is the list used to populate the ListView. My thinking was that I would be able to delete a row from the table and then repopulate this list as well as the ListView. I was also curious as to what happened to a SQLite table once a row is removed; do the other rows move up a position, or do they stay in the same place?
I am still very new to this so any help about my problem or tips for the rest of my code would be much appreciated. Let me know what else I'm doing wrong with my programming.
If you are using the SQLiteOpenHelper you should be getting a SQLiteDatabase object and then using a transaction, if you don't set it as successful then nothing will happen
SQLiteDatabase db = mDbHelper.getWritableDatabase();
db.beginTransaction();
//Do stuff
db.setTrasactionSuccessfull();
db.endTransaction();
Also I think when you pass null into the where clause the where doesn't matter.
You should have something like db.delete("tbl", "id=?", new String[]{String.valueOf(id)});
I am displaying data pulled from the Android OS sqlite database. I am successfully getting the items to delete when I click on them. However I am having an issue refreshing, or updating the listview after the operation.
Below is the code where I delete the contact.
deleteBtn = (Button)v.findViewById(R.id.deleteBtn);
deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Deleted: " + c.getId() + " " + c.getName(), Toast.LENGTH_SHORT).show();
adapter.deleteContact(c.getId());
updateList();
}
});
Below is the updateList() method:
public void updateList(){
myList.refreshDrawableState();
myList.invalidateViews();
this.notifyDataSetChanged();
}
I included in this method all three ways I tried to refresh but none worked for me. Any idea how I might achieve this?
EDIT: I changed my code thinking this would be the solution but it did not work either:
DbAdapter class delete method():
public boolean deleteContact(int rowId){
getAllContactsList();
return db.delete(DB_TABLE, COLUMN_ID + "=" + rowId, null) > 0;
}
getAllContactsList():
public List<Contact> getAllContactsList(){
List<Contact> contactList = new ArrayList();
Cursor c = db.query(DB_TABLE, new String [] {COLUMN_ID, COLUMN_FNAME, COLUMN_LNAME}, null, null, null, null, null);
//loop through cursor rows and add to list
if(c.moveToFirst()){
do{
Contact contact = new Contact();
contact.setId(Integer.parseInt(c.getString(0)));
contact.setfName(c.getString(1));
contact.setlName(c.getString(2));
contactList.add(contact);
}while(c.moveToNext());
}
return contactList;
}public List<Contact> getAllContactsList(){
List<Contact> contactList = new ArrayList();
Cursor c = db.query(DB_TABLE, new String [] {COLUMN_ID, COLUMN_FNAME, COLUMN_LNAME}, null, null, null, null, null);
//loop through cursor rows and add to list
if(c.moveToFirst()){
do{
Contact contact = new Contact();
contact.setId(Integer.parseInt(c.getString(0)));
contact.setfName(c.getString(1));
contact.setlName(c.getString(2));
contactList.add(contact);
}while(c.moveToNext());
}
return contactList;
}
I thought by getting a new cursor before deleting the contact It would update the list accordingly. Unfortunately It made no difference. Any ideas ?
You have to notify the list's adapter that you have modified the underlying data.
Try using adapter.notifyDataSetChanged();
It seems that you have the Database Adapter class, but you're missing the ArrayAdapter class, which is intended to manage the list of items, displayed in your ListView. Take a look at this example, specifically at the WeatherAdapter.java class.
If I am wrong in my assumptions and the adapter object in your code is not a database adapter, but an ArrayAdapter class, try putting adapter.notifyDataSetChanged() instead of this.notifyDataSetChanged().
Let me know if this helped.
You must requery and and generate new list:
public void updateList(){
clear();
addAll(contactsDbHelper.getAllContactsList()); //addAll works since 11 API version.
notifyDataSetChanged(); //need this is you dissabled auto notify
}
P.S. You should done this job with using Content providers and CursorAdapter, but you need manually notify content provider about changes, because Cursor.requery() is deprecated since 11 version.