I have a SQLite database that is converted into a listview and everything is working fine. But i am facing a problem now:
I have a column named stage in my database. Stage will contain one of these integers: 0, 1 or 2. In the layout file of the listview items i have a textview called status, and the value of stage is printed into this textview. But i don't want 0, 1 or 2 printed in the textview, i want to replace the integer with a word.
So for example if the value of stage is 0, i want the content of status to be "hello". And if the value of stage is 1, i want the content of status to be "goodmorning". I have tried multiple things but i don't get it working.
The code of the listview:
private DBManager dbManager;
private ListView listView;
private SimpleCursorAdapter adapter;
final String[] from = new String[] { DatabaseHelper._ID,
DatabaseHelper.IDEA, DatabaseHelper.DESC, DatabaseHelper.STAGE};
final int[] to = new int[] { R.id.id, R.id.idea, R.id.desc, R.id.status };
dbManager = new DBManager(this);
dbManager.open();
Cursor cursor = dbManager.fetch();
listView = (ListView) findViewById(R.id.list_view);
listView.setEmptyView(findViewById(R.id.empty));
adapter = new SimpleCursorAdapter(this, R.layout.activity_view_record, cursor, from, to, 0);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
I hope somebody can help me, thanks in advance :).
You could implement a custom adapter rather than using SimpleCursorAdapter and then change/convert the value in the getView or bindView method within the adapter.
Alternately you could change/convert the values via the query that returns the cursor. Along the lines of :-
SELECT col1, col2, (CASE WHEN colx = 0 THEN 'Hello' ELSE 'GoodMorning' END) AS mynewcolum FROM TABLE;
Where col1, col2 and colx are existing columns and colx is the column that is to be converted.
Try like this
Take
int i;
Then check
if (i==0) {
textview.setTe xt("hello");
} else if (i==1) {
textview.setText("good morning");
}
Related
I'm populating a spinner with a number of records from my SQlite database using the following code:
DBHelper db = new DBHelper(getBaseContext());
Cursor cursor_clients = db.select("clients", "_id, name", "ORDER BY name"); // table, fields, filter/order
String[] columns = new String[] { "name" };
int[] to = new int[] { android.R.id.text1 };
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, cursor_clients, columns, to, 0);
mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner spnClients = (Spinner) findViewById(R.id.spnClients);
spnClients.setAdapter(mAdapter);
It works great, and I can use
spnAcademias.getSelectedItemId();
To get the _id of the selected record. My problem is: How to select an item on this spinner by the _id?
I have the _id of the row I want, I want it to show this row selected, and not the first row coming from the query.
Doing more research I ended up with the solution here: setSelection on Spinner based on rowId
I thought maybe there was a native solution without a loop, but there is not.
Solution:
public void setSpinnerItemById(Spinner spinner, int _id)
{
int spinnerCount = spinner.getCount();
for (int i = 0; i < spinnerCount; i++)
{
Cursor value = (Cursor) spinner.getItemAtPosition(i);
long id = value.getLong(value.getColumnIndex("_id"));
if (id == _id)
{
spinner.setSelection(i);
break;
}
}
}
If you're able to just as easily get the text value of the row you are looking for, then try the solution here, and more specifically the top comment on it: Set selected item of spinner programmatically
Use the following: spinnerObject.setSelection(INDEX_OF_CATEGORY2).
...
... I also found a way of getting the index without needing to loop through the adapter. I used the following mySpinner.setSelection(arrayAdapter.getPosition("Category 2"));
Right now I am almost done writing my app. All I need is a bit help on getting the selected String value from a spinner populated from my database by a simple cursor adapter. I am not sure how I can get the String from my spinner and pass it to a different cursor and use the string in a query, that will populate depending on the first choice of the spinner, and so on with other spinners.
Here is the code I am using for one of my spinners.
vType = (Cursor) DataBaseHelper.getPowersportsType();
this.startManagingCursor(vType);
SimpleCursorAdapter scaType = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item,
vType,
new String [] {DataBaseHelper.POWERSPORTS_TYPE},
new int[] {android.R.id.text1});
scaType.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
vTypeSpinner = (Spinner) findViewById(R.id.typeSpinner);
vTypeSpinner.setAdapter(scaType);
And this is my query for the next spinner in my xml layout
static String MakeWhere = "POWERSPORTS_TYPE=?";
public static Cursor getPowersportsMake(){
return myDataBase.query(POWERSPORTS_TABLE,
new String [] {POWERSPORTS_ID, POWERSPORTS_MAKE},
MakeWhere,
null,
POWERSPORTS_MAKE,
null,
null);
}
Any comments or suggestions are welcomed.
to get the item selected you need to set the onItemSelectedListener
then in your onItemtSelected all you would do is
String selection = vTypeSpinner.getSelectedItem().toString();
I extended SimpleCursorAdapter according to my needs. I want to show two textviews in a row.
One of these textviews is filled by the cursor but for the other one I want to use an ArrayList. Let me give an example to clarify:
For the first field I use the data from cursor
String[] columns = new String[] { ContactsContract.PhoneLookup.DISPLAY_NAME };
int[] to = new int[] { R.id.toptext };
I want to use ArrayList for the second field so that they form the following listview
I don't know how I can set the second field. Any help would be appreciated.
I haven't tested it but you could use the _id column of your query to map your values to the list and later bind the data.
private HashMap<Long, String> items = new HashMap<Long, String>(); // this will map the ids from the cursor to the values in the ArrayList
//get the cursor Cursor cursor = the query and then map the values:
int tmp = 0;
while (mc.moveToNext()) {
items.put(mc.getLong(mc.getColumnIndex("_id")), extra.get(tmp)); //or replace _id with your ID column from the query
tmp++;
}
Then pass this HashMap to your custom adapter constructor:
private HashMap<Long, String> extraStuff;
public YourCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to, HashMap<Long, String> extraSutff) {
// stuff
this.extraStuff = extraStuff;
}
and bind the values in the bindView() method:
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView top = (TextView) view.findViewById(R.id.toptext);
top.setText(cursor.getString(cursor.getColumnIndex(THE_COLUMN_FOR_THE_FIRST_TEXTVIEW)));
TextView bottom = (TextView) view.findViewById(R.id.bottomtext);
bottom.setText(extraStuff.get(cursor.getLong(cursor.getColumnIndex(THE_ID_COLUMN_FROM_THE_QUERY))));
}
Note: I don't know how efficient this will be if you have many rows in the cursor.
Here is my code to retriev the data from db to a listview.
private void fillData() {
Cursor c = viewDB.fetchAllRows();
startManagingCursor(c);
String[] from = new String[] { ViewComplaintsDataDB.KEY_NUMBER,
ViewComplaintsDataDB.KEY_DESCRIPTION,
ViewComplaintsDataDB.KEY_LOGGEDBY }; //these three are the fields in my db
int[] to = new int[] { R.id.com_num, R.id.com_desc , R.id.user }; //these three are the textview id's in my listitem.xml file
SimpleCursorAdapter simple = new SimpleCursorAdapter(this,
R.layout.listitem, c, from, to);
setListAdapter(simple);
}
This is working.
There is a lot of data in each row under the second column in my DB. How can i display only 50 characters of data from the second field to the listview. Please help me.
You could just set the maxLength atribute from the textView to 50.
<TextView
android:text="TextView"
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="50"></TextView>
for that you need to ArrayAdapter instead of SimpleCursorAdapter and fetch the data required to show from the DB and set it to the adapter....
I have a Spinner which is to show a list of data fetched from database. The data is returned to a cursor from query, and the cursor gets passed to spinner's SimpleCursorAdapter. It is working fine as such, but I want to insert another item on top of this data. For example, the spinner is already showing a list of user created templates saved in DB, but I want to insert "New Template" and "Empty Template" on top of the list of templates, and it needs to be inserted into Cursor/SimpleCursorAdapter somehow.
I have considered using an arraylist and populating the arraylist from cursor, but cursor is better solution for me since it contains other related rows of data too. I searched internet for other solutions and found some answers asking to use CursorWrapper for this purpose, but I could not find a concrete example how to use CursorWrapper to accomplish what I want. How can I insert some rows in cursor or can someone please give a easy to follow CursorWrapper example!! Thanks in advance.
You can use a combination of MergeCursor and MatrixCursor with your DB cursor like this:
MatrixCursor extras = new MatrixCursor(new String[] { "_id", "title" });
extras.addRow(new String[] { "-1", "New Template" });
extras.addRow(new String[] { "-2", "Empty Template" });
Cursor[] cursors = { extras, cursor };
Cursor extendedCursor = new MergeCursor(cursors);
This is the method I tried.
MatrixCursor m = new MatrixCursor(c.getColumnNames());
Cursor c = DBHelper.rawQuery("Select values from your_table");
MatrixCursor m = new MatrixCursor(c.getColumnNames());
//Use MatrixCursor#addRow here to add before the original cursor
while (c.moveToNext()) {
//Use MatrixCursor#addRow here to add before the original row
DBHelper.insertRow(c, m);
//Use MatrixCursor#addRow here to add after the original row
}
//Use MatrixCursor#addRow here to add after the original cursor
m.addRow(new String[]{col1Val, col2Val, col3Val,..., //to match the number of columns needed});
DBHelper.insertRow()
public final static void insertRow(Cursor from, MatrixCursor to) {
final String columns[] = from.getColumnNames(), values[] = new String[columns.length];
final int size = columns.length;
for (int i = 0; i < size; i++) {
values[i] = getStringFromColumn(from, columns[i]);
}
to.addRow(values);
}
With this method, you can add any amount of rows anywhere in your cursor. Even though it is not making use of CursorWrapper, it can be used with CursorAdapters or SimpleCursorAdapters.
I tried the solution provided by #naktinis, but the result wasn't what I expected. What I myself wanted to achieve as an adapter in which new elements can be added at the top (index 0). However, with the solution given, new elements were indeed added at the top but only to the END of the MatrixCursor. In other words, when I added rows dynamically to the "extras" MatrixCursor, I got something like this:
"extras" row 1
"extras" row 2
"extras" row 3
"cursor" row 1
"cursor" row 2
"cursor" row 3.
However, what I really wanted to achieve was something like this:
"extras" row 3
"extras" row 2
"extras" row 1
"cursor" row 1
"cursor" row 2
"cursor" row 3.
In other words, most recent elements enter at the top (index 0).
I was able to achieve this manually by doing the follow. Note that I did not include any logic to handle dynamically removing elements from the adapter.
private class CollectionAdapter extends ArrayAdapter<String> {
/**
* This is the position which getItem uses to decide whether to fetch data from the
* DB cursor or directly from the Adapter's underlying array. Specifically, any item
* at a position lower than this offset has been added to the top of the adapter
* dynamically.
*/
private int mCursorOffset;
/**
* This is a SQLite cursor returned by a call to db.query(...).
*/
private Cursor mCursor;
/**
* This stores the initial result returned by cursor.getCount().
*/
private int mCachedCursorCount;
public Adapter(Context context, Cursor cursor) {
super(context, R.layout.collection_item);
mCursor = cursor;
mCursorOffset = 0;
mCachedCursorCount = -1;
}
public void add(String item) {
insert(item, 0);
mCursorOffset = mCursorOffset + 1;
notifyDataSetChanged();
}
#Override
public String getItem(int position) {
// return the item directly from underlying array if it was added dynamically.
if (position < mCursorOffset) {
return super.getItem(position);
}
// try to load a row from the cursor.
if (!mCursor.moveToPosition(position - mCursorOffset)) {
Log.d(TAG, "Failed to move cursor to position " + (position - mCursorOffset));
return null; // this shouldn't happen.
}
return mCursor.getString(INDEX_COLLECTION_DATA);
}
#Override
public int getCount() {
if (mCachedCursorCount == -1) {
mCachedCursorCount = mCursor.getCount();
}
return mCursorOffset + mCachedCursorCount;
}
}