I am trying to build a simple stock application, I have a list view on my main activity which has a "Sell" button on every list item I have. The functionality of the Sell button should decrease the quantity of that particular item by updating the row for that item and setting the quantity to quantity-1.
To achieve this, I have found that setting up an on click listener in my custom cursor adapter class was the way to do it. I am using a content provider class for my Database operations. So what I tried to do is, trigger a function which is in my main activity, within the OnClickListener which is in my cursor adapter. Here is some code that would explain more. (please forgive my terrible programming skills, I am fairly new )
My approach does not seem to work for some reason, first click on Sell button does not do anything, and the second one crashes the application with the reason:
android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method.
p.s. I did not send the context from the adapter to decrease count method, and it was crashing of a null pointer on the getContentResolver().
Update function in my content provider:
private int updateItem (Uri uri, ContentValues values, String selection, String[] selectionArgs){
if (values.containsKey(InventoryContract.ItemEntry.COLUMN_NAME)){
String name = values.getAsString(InventoryContract.ItemEntry.COLUMN_NAME);
if (name == null){
throw new IllegalArgumentException("Item requires a name");
}
}
// If values size is zero, do not try to update the database.
if (values.size() == 0){
return 0;
}
// Otherwise, get writeable database to update the data
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Perform the update on the database and get the number of rows affected
int rowsUpdated = database.update(InventoryContract.ItemEntry.TABLE_NAME, values, selection, selectionArgs);
// If 1 or more rows were updated, then notify all listeners that the data at the
// given URI has changed
if (rowsUpdated != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
// Return number of rows updated
return rowsUpdated;
}
The function I have written ( or tried to write ) in my main activity
public void decreaseCount(Context context, int columnId, int quantity){
quantity = quantity -1;
ContentValues values = new ContentValues();
values.put(InventoryContract.ItemEntry.COLUMN_QUANTITY, quantity);
Uri updateUri = ContentUris.withAppendedId(InventoryContract.ItemEntry.CONTENT_URI, columnId);
int rowsAffected = context.getContentResolver().update(updateUri, values,null, null);
}
and lastly, the custom OnClickListener I have added to the button (p.s. the listener is inside the overriden bindView method of the cursor adapter )
sellButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int columnIdIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry._ID);
int quantityIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry.COLUMN_QUANTITY);
CatalogActivity catalogActivity = new CatalogActivity();
catalogActivity.decreaseCount(context2, Integer.valueOf(mCursor.getString(columnIdIndex)), Integer.valueOf(mCursor.getString(quantityIndex)));
}
});
Thank you in advance !
The problem is very trivial. I fixed your codes. First don't create objects out of activities. Try to use boxing and unboxing technic to retrieve your context back. In your InsertCursorAdapter constructor should be like this
public ItemCursorAdapter(Context context, Cursor c) {
super(context, c);
this.context = context;
}
Then you need to save your cursor from bindView method.
Then you need to bind the context object to get your activity object back. All in all, you would have something like this:
#Override
public void bindView(View view, final Context context, Cursor cursor) {
this.mCursor = cursor;
TextView nameTextView = view.findViewById(R.id.name);
TextView quantityTextView = view.findViewById(R.id.quantity);
sellButton = view.findViewById(R.id.sell_button);
ImageView imageView = view.findViewById(R.id.item_image);
sellButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int columnIdIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry._ID);
int quantityIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry.COLUMN_QUANTITY);
String col= mCursor.getString(columnIdIndex);
String quan= mCursor.getString(quantityIndex);
CatalogActivity catalogActivity = (CatalogActivity) context;
catalogActivity.decreaseCount( Integer.valueOf(col), Integer.valueOf(quan));
}
});
Also I changed your decreaseCount arguments. Because this method is in activity class you don't need to pass it anytime you need to decrease the value. getContentResolver() method is a method in super class AppCompatActivity and because it is public, your activity have implemented it already.
//TODO: Decrease count by one
public void decreaseCount(int columnId, int quantity){
quantity = quantity -1;
ContentValues values = new ContentValues();
values.put(InventoryContract.ItemEntry.COLUMN_QUANTITY, quantity);
Uri updateUri = ContentUris.withAppendedId(InventoryContract.ItemEntry.CONTENT_URI, columnId);
int rowsAffected = getContentResolver().update(updateUri, values,null, null);
}
Related
I'm creating a method to read all the information in the database and view it through a spinner here is the code i tried for this function
public Spinner loadArtist(){
SQLiteDatabase DB = getReadableDatabase();
String[] projection = {
ArtistMaster.Artist.ARTIST_NAME};
Cursor cursor = DB.query(
ArtistMaster.Artist.TABLE_ARTIST,
projection,
null,
null,
null,
null,
null);
Spinner itemIds = new ArrayList<>();
while(cursor.moveToNext()) {
long itemId = cursor.getLong(
cursor.getColumnIndex(ArtistMaster.Artist.ARTIST_NAME));
itemIds.setAdapter(itemId);
}
cursor.close();
return itemIds;
}
but it gives me an error in this line Spinner itemIds = new ArrayList<>();
Should i declare it as a list instead of spinner
itemIds should be defined as an ArrayList<Long>. A Spinner is a UI element and an ArrayList is a data structure. You will most likely need to map the data to your UI using an adapter of some sort, eg. an ArrayAdapter:
Spinner spinner = ... // findViewById, new Spinner() etc.
ArrayList<Long> itemIds = new ArrayList<>();
//... fill array with artist IDs
spinner.setAdapter(
new ArrayAdapter(
this, // Context, Activity etc.,
android.R.layout.simple_list_item_1, // Spinner TextView item resource ID
itemIds // Data set.
));
By default, ArrayAdapter will call Object#toString() on each data object in the collection.
I'd suggest that it would be easier if you used a Cursor Adpater as they are designed to be used with a Cursor and there is no need to generate arrays.
SimpleCursorAdapter being that, a simple but still pretty flexible adapter for use with Cursors.
The only issue is that a Cursor Adapter requires a column name specifically _id (BaseColumns._ID resolves to this (as used below)).
First have the following member variables (obviously names can be what you wish)
:-
Cursor mCursor;
SimpleCursorAdapter mAdapter;
Spinner spinner;
SQLiteDatabase db;
In the onCreate Method of the activity have
:-
spinner = this.findViewById(R.id.?????); //
db = ???????? (as per your existing code)
manageSpinner();
Have a method
:-
private void manageSpinner() {
mCursor = db.query(
ArtistMaster.Artist.ARTIST_NAME,
new String[]{"*","rowid AS " + BaseColumns._ID}, //<<<<<<<< adds _ID column (unless the table is a WITHOUT ROWID table, pretty unlikely)
null,null,null,null,null
);
if (mAdapter == null) {
mAdapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
mCursor,
new String[]{"the_column"}, // column(s) from which to extract data
new int[]{android.R.id.text1}, // layout views into which the data is placed
0
);
spinner.setAdapter(mAdapter);
// You want want to do something when an Item in the spinner is clicked (this does nothing as it is)
spinner.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//........... do your stuff here
// notes
// id will be the id of the row
// cursor will be positioned, so you can access data from the cursor if needed
}
});
} else {
mAdapter.swapCursor(mCursor);
}
}
Override the activity's onResume (refresh the spinner when returning to activity as underlying data may have changed) and onDestroy (to close the Cursor) methods using
:-
#Override
protected void onDestroy() {
super.onDestroy();
mCursor.close();
}
#Override
protected void onResume() {
super.onResume();
manageSpinner();
}
I can't get this working. I want the item from list view to be deleted when I click on the button. But I really don't know how to implement this.
Here is my adapter
public class PersonalRecordsAdapterDialog extends CursorAdapter {
public PersonalRecordsAdapterDialog(Context context, Cursor c) {
super(context, c);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.list_view_personal_layout, parent, false);
}
#Override
public void bindView(View view, Context context, final Cursor cursor) {
final DatabaseAdapter db = new DatabaseAdapter(context);
TextView weightTV = (TextView) view.findViewById(R.id.weight_tv);
TextView dateTV = (TextView) view.findViewById(R.id.date_tv);
final Button deleteRecord = (Button) view.findViewById(R.id.delete_record);
final String id = cursor.getString(cursor.getColumnIndex(DatabaseAdapter.DatabaseHelper.COL_1));
String weight = cursor.getString(cursor.getColumnIndex(DatabaseAdapter.DatabaseHelper.COL_3));
String date = cursor.getString(cursor.getColumnIndex(DatabaseAdapter.DatabaseHelper.COL_4));
weightTV.setText(weight);
dateTV.setText(date);
deleteRecord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db.remove(Integer.parseInt(id));
notifyDataSetChanged();
}
});
}
}
and here is my ListView
AlertDialog.Builder builder = new AlertDialog.Builder(holder.mContext);
View dialogView = View.inflate(holder.mContext,R.layout.dialog, null);
ListView myList = (ListView) dialogView.findViewById(R.id.dialog_list_view);
Cursor cursor = holder.myDb.getRows(exercise[position]);
PersonalRecordsAdapterDialog adapter = new PersonalRecordsAdapterDialog(holder.mContext,cursor);
myList.setAdapter(adapter);
builder.setView(dialogView)
.setTitle("History of your " + exercise[position].toLowerCase() + " records")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// sign in the user ...
}
});
AlertDialog b = builder.create();
b.show();
Thank you for your help
Remove the item from your model when onClick happens n call notifyDatasetChanged() for the same adapter
and in your case you are passing cursor directly to your custom adapter which is a very bad practice as in this case your connection with the db will stay open and can lead to Memory and DB issues
So you can create your own model (ArrayList) , get values from cursor, add them into your model,Close your db connection and pass that model to your adapter. and to remove a particular item remove that from your model and call notifyDatasetChanged().(Note: Removing from model will only remove the data from list but not from db. In case you want to delete that data from your db, you also have to execute Delete Query )
for this : I don't want to delete it when I click on ListView item. I want to delete it only when I click on button in ListView item
Go to your adapter class.. get the object instance over there in OnGetView(...) method and the the onClickListener for the same over there.
To delete row from DB you can use a unique id from db table like this
public void delete_byID(int id){
sqLiteDatabase.delete(MYDATABASE_TABLE, KEY_ID+"="+id, null);
}
Where MYDATABASE_TABLE is your table to delete from.
KEY_ID is the name of the coloumn to put where condition.
id is the unique id associated with the row you want to delete
So in this case you will not need the cursor to delete a particular record
The reason that bindView method doesn't refresh by the db change is :
The cursor is steel the old cursor .
You need to requery the data base get new cursor and then
Call adapter.change cursor(passHereTheNewCursor)
Adding to above answer by Nitesh - To delete item from listview on button click, Either 1. first you need to delete item from listview's adapter like below -
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Object objToRemove = adapter.getItem([POSITION]);
adapter.remove(objToRemove);
}
}
or 2. you can delete this item from your arrayList & call notifyDataSetChanged().
But this will not delete from database. you have to implement delete query for it.
and yes as above said -
in your case you are passing cursor directly to your custom adapter which is a very bad practice as in this case your connection with the db will stay open and can lead to Memory and DB issues.
I have a list view and a database I want to display the data from the database in another activity so I made a OnItemClickListener for my list view.
Now I get the position of the ClickListener but because I have made my adapter to display data so the latest input from the user is on top. I nead to reverse the position of the onClick.
At the moment I get:
1
2
3
4
but I need:
4
3
2
1
because of the database id.
If for example the user clicks position 3 on the list I want the database to return the row 3.
ListView:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
Intent myIntent = new Intent(getActivity(), JornalListViewClick.class);
myIntent.putExtra("intVariableName",position);
startActivity(myIntent);
}
});
The getRows of the database:
public Cursor getAllRowre(){
String where=null;
Cursor cursor=db.query(true, DATABASE_TABLE, ALL_KEY, where, null, null, null,ID_KEY + " DESC", null);
if(cursor!=null){
cursor.moveToFirst();
}
return cursor;
}
The activity where I want to display the data:
Intent mIntent = getIntent();
int intValue = mIntent.getIntExtra("intVariableName", 0);
intValue++;
text=(TextView) findViewById(R.id.textViewUserInputFromListClicked);
Cursor cursor=dbJ.getRowUserInput(intValue+"");
if(cursor.moveToFirst()){
do{
String mes=cursor.getString(0);
text.setText(mes);
}while(cursor.moveToNext());
}
An alternative way:
Use a POJO to store every row retrieved
Implement Comparator and use Collections.sort(List, Comparator) to sort it before putting it into adapter
public class MyData{
private String field;
// getter and setter
}
After retrieve the String from database, you can instantiate MyData class and set the string (or more fields) into the instance. Put all results in a Collection. E.g.:
Vector<MyData> listOfResults=new Vector<MyData>();
if(cursor.moveToFirst()){
do{
String mes=cursor.getString(0);
MyData instance=new MyData();
listOfResults.add(instance);
}while(cursor.moveToNext());
}
return listOfResults;
After retrieving data from database, you want to sort it, right? Try this:
Collections.sort(listOfResults,new Comparator<MyData>(){
public int compareTo(MyData a,MyData b){
return a.getField().compareTo(b.getField());
}
});
Inside the Activity containing the ListView, create a private class implementing ListAdapter. E.g.:
private class MyListAdapter implements ListAdapter{
private Vector<MyData> data;
public MyListAdapter(Vector<MyData> list){
data=list;
}
/*** other methods you need to implement ***/
}
Instantiate MyListAdapter by supplying the Vector you got from database access method.
Then call setAdapter(ListAdapter) of the ListView inside the Activity after the data is ready.
I'm developing an android app which shows phone contact as ListView(used Cursoradapter).Now I Want to add checkbox to the listView ,My problem is How to Insert checkbox data into database, based on if it is checked or not?
In my database class, I have a function which use to add names and numbers to my database,
createntry(String number,String name) // in my database class
Should I invoke this function in my CursorAdapter class ?
Recently, I found out that I should use getView function,but unfortunately I have no idea about getView, My question are
1-I should use this function in My CursorAdapter or else?
2- how to implement this function?
My CursorAdapterClass
public class ContactCursorAdapterCT extends CursorAdapter {
public ContactCursorAdapterCT(Context context, Cursor c) {
super(context, c);
}
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView name = (TextView)view.findViewById(R.id.contactlistTV1);
name.setText(cursor.getString
(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
TextView phone = (TextView)view.findViewById(R.id.contactlistTV2);
phone.setText(cursor.getString
(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.lvct, parent, false);
bindView(v, context, cursor);
return v;
}
public View getView(final int pos, View inView, ViewGroup parent) { //getView
}
My activity class
public class Contacts extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.contacts);
Cursor cursor = getContentResolver().query
(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,null, null);
startManagingCursor(cursor);
ContactCursorAdapterCT adapter= new ContactCursorAdapterCT
(Contacts.this, cursor);
ListView contactLV = (ListView) findViewById(R.id.listviewblcontactsDB);
contactLV.setAdapter(adapter);
My database Class
public long creatEntry(String inputnumber , String name) { // for add data
// TODO Auto-generated method stub
ContentValues cv= new ContentValues();
cv.put(KEY_NUMBER, inputnumber);
cv.put(N_NAME, name);
Log.v(inputnumber, "adding to Database");
return ourdatabase.insert(DATABASE_TABLE, null, cv);
}
Firstly, no you don’t need getView. bindView in conjunction with newView is completely sufficient as a replacement for it, some would probably say even better. Moreover, you don’t need to call bindview in new view. here’s a restructuring of what should be there.
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = inflater.inflate(R.layout.lvct, parent, false);
return v;
}
This is totally your call but no I don’t think that you should your createEntry method into the adapter, at least in its methods. The thing is that methods in the adapter are called for each row of your listview, so you might have a lot happening redundantly and plus I personally find it wasteful to be making insertions into a database into in increments. rather I think you have no choice but to do it all at once, because what if someone unselects a checkbox? you delete your entry? not only is it wasteful but it would be too cumbersome to keep track of the cursor positions or _id, you’d need to re-query every-time that something had been added. What you should do is maintain a list of what needs to be added to the database and bulk insert it when it’s done.
First you need to make an object holding the data that you want inserted. An object is the cleanest way cause you need to hold multiple pieces of information. Here it is very simple, you insert values you want into the constructor and then retrieve with the getter methods.
public class ContactObject {
private String name;
private String phone;
public ContactObject(String name, String phone) {
super();
this.name = name;
this.phone = phone;
}
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
}
Now you need an object to hold these objects when they’re checked. weird I know, but it much more convenient if they’re identified and can be iterated over and in general are batched together for referencing. I think this sort of task calls for the HashMap. Make it in the constructor.
contactMap = new HashMap<Integer, ContactObject>(c.getCount());
Now it’s time to boogie. make methods for the checkbox to add and remove stuff from your HashMap.
cbInsert.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (cbInsert.isChecked()) {
contactMap.put(cursor.getPosition(), new ContactObject(str_name, str_phone));
} else {
contactMap.remove(cursor.getPosition());
}
}
});
We’ve used the cursor position like an id for our objects within the HashMap. And when our checkbox is unchecked and we want to remove the object that was put in, we can just refer that that identifier that we used. Someone more prudent might want to check if something is there at the position before removing, that’s at your discretion. Now we’re almost done. How do we convert our HashMap to entries in the database? You have to access a database object, loop through and then get at your object one by one. The question is now is where. You could do it right in the adapter, but I usually do something like this in my activity because in my cases I usually have a database already made for the activity for other tasks and I don’t like to make more objects than I’m pushed to. So, what we can do is finish up with a getter method in our adapter for our HashMap:
public HashMap<Integer, ContactObject> getContactMap() {
return contactMap;
}
Now I’d imagine that you’d do something like this when your app is leaving so here goes.
#Override
protected void onDestroy() {
super.onDestroy();
HashMap<Integer, ContactObject> contactMap = adapter.getContactMap();
DatabaseHelper db = new DatabaseHelper(this);
// iterate through hashmap
for (Map.Entry<Integer, ContactObject> entry : contactMap.entrySet()) {
Integer key = entry.getKey();
ContactObject value = entry.getValue();
db.creatEntry(key, value.getPhone(), value.getName());
}
db.close();
}
Now things look a little weird, what happened what did i do with your entry method?
public long creatEntry(Integer id, String inputnumber, String name) { // for add data
long lng;
String strId = id.toString();
String[] selectionArgs = {strId};
Cursor cursor = ourdatabase.query(DATABASE_TABLE, null, "other_id = ?", selectionArgs, null, null, null);
if (cursor.moveToFirst()) {
// it exists, i'd assume that you might not want anything else done here
lng = -1;
} else {
// it doesn't exist
ContentValues cv= new ContentValues();
cv.put(KEY_NUMBER, inputnumber);
cv.put(N_NAME, name);
cv.put(KEY_OTHERID, strId);
Log.v(inputnumber, "adding to Database");
lng = ourdatabase.insert(DATABASE_TABLE, null, cv);
}
// cursor.close();
return lng;
}
As you can i see I modified it so that it takes in the id as well. I thought that you an issue that you'd run into would be having repeats in your database. I thought you could manage it by having another field for an id that you can modify.This id refers to the id passed in from the HashMap. I figured that every time that you make an insertion you first check if that previous id is there, then decide what you want to do. This is not a perfect solution but i just wanted to alert you that that issue is possible and give a possible hint as to manage it. In general the insert method should be fine if you only want to insert a couple rows but if you have a lot of stuff to insert, you might wanna look into bulk transactions for performance.
One more thing, checkboxes in your listview cannot be expected to have their states persist as you might normally expect it. You must explicitly dictate what state the checkbox has at each position. I made it correspond with if your HashMap has something filled with its corresponding key. Here's the full adapter method in hopes that it's made clearer:
public class ContactCursorAdapterCT extends CursorAdapter {
private LayoutInflater inflater;
private HashMap<Integer, ContactObject> contactMap;
public ContactCursorAdapterCT(Context context, Cursor c) {
super(context, c);
inflater = LayoutInflater.from(context);
contactMap = new HashMap<Integer, ContactObject>(c.getCount());
// i used c.getCount() as a capacity limit for this.
// if you opened made this multiple times, it might get over inflated and
// slow things down.
}
#Override
public void bindView(View view, Context context, final Cursor cursor) {
TextView name = (TextView)view.findViewById(R.id.contactlistTV1);
TextView phone = (TextView)view.findViewById(R.id.contactlistTV2);
final CheckBox cbInsert = (CheckBox) view.findViewById(R.id.contactlistCB1);
String str_name = cursor.getString
(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String str_phone = cursor.getString
(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
name.setText(str_name);
phone.setText(str_phone);
boolean isFilled = contactMap.containsKey(cursor.getPosition());
cbInsert.setChecked(isFilled);
// insert, remove objects to hashmap
cbInsert.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (cbInsert.isChecked()) {
contactMap.put(cursor.getPosition(), new ContactObject(str_name, str_phone));
} else {
contactMap.remove(cursor.getPosition());
}
}
});
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = inflater.inflate(R.layout.lvct, parent, false);
return v;
}
public HashMap<Integer, ContactObject> getContactMap() {
return contactMap;
}
}
It would be a good idea to add a flag to your records which will indicate that they are checked or not. Meaning an entry will have a name, a number and a flag (checked/unchecked).
In your Adapter itself, you can check the value of this flag an act accordingly.
(A related answer was regarding checkboxes in ListView is given here)
I'm overriding CursorAdapter and I need to get the last item, problem is that CursorAdapter has actually a get() method...but source is a db and it returns a plain object!! (I don't even know what is it, I'd expect it returning a Cursor object instead...)
Neverthless, how can I make it return an instance of my Wrapper db row class?
Example:
say my db has rows like these:
id|first name| surname
I'd make a class Person from that.
Now I'd like to have a Person get(int i) method from cursor adapter...
well just use the adapter.getItem() and cast it to Cursor, and there is no need to move the cursor manually like in accepted answer
Cursor cursor = (Cursor) myCursorAdapter.getItem(position);
String myColumnValue = cursor.getString(cursor.getColumnIndex("YOUR_COLUMN_NAME"));
Now I'd like to have a Person get(int i) method from cursor adapter...
This seems like a strange request. I would pass the Cursor itself (or the Cursor returned from CursorAdapter's getItem()) to a regular method in my Activity instead. But here are the basic steps to create a Person get() method.
Create your Person class:
public class Person {
long id;
String firstName;
String surname;
}
And in your custom CursorAdapter simply use a method like this:
public Person get(int position) {
Cursor cursor = getCursor();
Person person;
if(cursor.moveToPosition(position)) {
person = new Person();
person.id = cursor.getLong(cursor.getColumnIndex("_id"));
person.firstName = cursor.getString(cursor.getColumnIndex("firstName"));
person.surname = cursor.getString(cursor.getColumnIndex("surname"));
results.add(person);
}
return person;
}
Well, i had to debug to find the answer. Suppose you have something like this with
SimpleCursorAdapter
themesAdapter = new SimpleCursorAdapter(getContext(), R.layout.spinner_with_count, null,
new String[]{ThemeData.COLUMN_ID, ThemeData.COLUMN_SET_COUNT}, new int[] { R.id.spinnerTxLabel, R.id.spinnerTxCount }, 0);
inputTheme.setAdapter(themesAdapter);
Then you have to retrieve like this way.
inputTheme.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// if not all themes, get subthemes items
if(position > 0){
// load subtheme
Cursor currentCursor = (Cursor)inputTheme.getAdapter().getItem(position);
if(currentCursor != null) {
String value = currentCursor.getString(currentCursor.getColumnIndexOrThrow(Data.COLUMN_ID));
}
}
}
};