Android ListView and SimpleCursosrAdapter: nothing is showed - android

A read a lot of docs, but can't figure out what I am doing wrong. I'm just trying to load data with Cursor and show it in a ListView using SimpleCursorAdapter.Here is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_expense_category);
DBHelper dbHelper = new DBHelper(this);
SQLiteDatabase db = dbHelper.getReadableDatabase();
String q = "SELECT rowid as _id, " + GLO.DBEntry_Categories.COLUMN_CATEGORY +
" FROM " + GLO.DBEntry_Categories.TABLE_NAME;
Cursor cursor = db.rawQuery(q, new String[]{});
cursor.moveToFirst();
Toast toast = Toast.makeText(this, "Read count: " + Integer.toString(cursor.getCount()) + " " + cursor.getString(0), Toast.LENGTH_LONG);
toast.show();
cursor.moveToFirst();
//TODO: use Loader
String[] fromCols = {GLO.DBEntry_Categories.COLUMN_CATEGORY};
int[] toViews = {R.id.MyTextView1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor,
fromCols, toViews, 0);
ListView listView = (ListView) findViewById(R.id.SelectExpenseCategory_list);
listView.setAdapter(adapter);
}
So toast message shows there are 3 items in cursor, and data is peresent (at least in first one, but I'm sure for others too). But nothing is showed in ListView.
Here is a part of my activity layout:
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/SelectExpenseCategory_search"
android:layout_centerHorizontal="true"
android:id="#+id/SelectExpenseCategory_list">
</ListView>
And here is complete file for item layout:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/MyTextView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="5dp"
android:textColor="#color/cm_dark_green"
android:textSize="24sp">
</TextView>
Any ideas what's wrong?..

You're using the internal layout for the list items: android.R.layout.simple_list_item_1.
The TextView id there is called text1, so instead use this:
int[] toViews = {android.R.id.text1};
If you want to use your own custom layout then change the layout used by your adapter to e.g. R.layout.list_item_layout.

Related

Populate spinner from simple cursor adapter

I have some trouble to populate spinner from sqlite database with simple cursor adapter. I must use simple cursor adapter not array adapter. My MainActivity, functions and xml files are as follows:
public class MainActivity extends BaseActivity {
private Spinner workerId = (Spinner) findViewById(R.id.spinner);
c = getCursor();
String[] columns = new String[]{Database.mylist};
int[] to = new int[] { R.id.spinner };
myAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, c, columns,to, 0);
workerId.setAdapter(myAdapter);
..............
..............
}
Function is below:
public Cursor getCursor() {
Cursor c = database.rawQuery("select * from " + Database.mylist + " where isCancel = 0", null);
return c;
}
Xml file is below;
MainActivity.xml
<Spinner
android:id="#+id/spinner"
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:layout_height="wrap_content" />
And when I run app the following screen displays. There is data but it seems empty. I have _id, name columns.
empty spinner
Thank you for your help.
Change
int[] to = new int[] { R.id.spinner };
to
int[] to = new int[] { android.R.id.text1 };
And you can read a little bit more about SimpleCursorAdapter here: Android: Using SimpleCursorAdapter to get Data from Database to ListView
Also you are using Database.mylist as column name and table name as PPartisan pointed out in a comment.

adding values to listView

I am trying to populate a ListView....but I cant add 2 string values from database used in SimpleCursorAdapter....
Any one, help me
Code
ListView.java
public class ListView extends ListActivity {
SQLiteDatabase messagedb;
List<String> senderArray = new ArrayList<String>();
List<String> bodyArray = new ArrayList<String>();
String[] simpleSenderArray = new String[ senderArray.size() ];
String[] simpleBodyArray = new String[ bodyArray.size() ];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_list);
senderArray.toArray( simpleSenderArray );
bodyArray.toArray( simpleBodyArray );
messagedb=ListView.this.openOrCreateDatabase("message",0, null);
//This database created already and add sender and body values...here just open that database
Cursor cur=messagedb.rawQuery("select sender, body from tab2", null);
while(cur.moveToNext())
{
String sender = cur.getString(cur.getColumnIndex("sender"));
String body = cur.getString(cur.getColumnIndex("body"));
senderArray.add(sender);
bodyArray.add(body);
}
cur.close();
messagedb.close();
int[] to = new int[] { R.id.sender_entry, R.id.body_entry };
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.my_list_entry, cur,simpleSenderArray, to);
this.setListAdapter(mAdapter);
}
}
my_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ListView
android:id="#android:id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
my_list_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/sender_entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="28dip" />
<TextView
android:id="#+id/body_entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="28dip" />
</LinearLayout>
Can somebody help me to populate my ListView?
You have named your Activity ListView which is already a built-in class name, I highly recommend changing it to something unique to prevent any confusion or naming conflicts.
In your SQLite table, you ought to have an _id INTEGER column set as the PRIMARY KEY, Android requires this _id column to bind the data to any ListView, Spinner, etc. (Technically SQLite3 creates a column like this automatically, but I believe it is best to define it yourself.)
messagedb.execSQL(
"CREATE TABLE IF NOT EXISTS tab2(" +
" _id INTEGER PRIMARY KEY," +
" sender INT(13)," +
" body varchar)");
Your code should look more like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_list);
// Using a SQLiteOpenHelper might be best, but I'll assume that this command works
messagedb=ListView.this.openOrCreateDatabase("message",0, null);
Cursor cur = messagedb.rawQuery("select _id, sender, body from tab2", null);
String[] from = new String[] { "_id", "sender", "body" }
int[] to = new int[] { R.id.sender_entry, R.id.body_entry };
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.my_list_entry, cur, from, to);
this.setListAdapter(mAdapter);
}
You might want to consider using the SQLiteDatabase.query() methods, I believe it is a touch faster:
Cursor cur = messagedb.query("tab2", new String[] {"_id", "sender", "body"}, null, null, null, null, null);
I also recommend defining static variables for all you column names for future ease-of-coding.
Lastly, this should work for a table without the _id column, but again I don't recommend it:
Cursor cur = messagedb.rawQuery("select rowid as _id, sender, body from tab2", null);

Keep bouncing between errors, can't find good fix for Spinner/Adapter

I can't seem to figure out this SimpleCursorAdapter, every time I fix one error, another one pops up and if I follow the steps to fix that one, the first one comes up again. I feel like I'm going in circles here, so here's the chunk of code I'm trying to debug, note, the first part is just creating the DB, but I figured anything could be helpful in figuring it out.
SQLiteDatabase rpgDB = null;
String classFields = " (classID, className, classHP)";
try {
rpgDB = this.openOrCreateDatabase("RpgDB", MODE_PRIVATE, null);
rpgDB.execSQL("DROP TABLE IF EXISTS " + classTable);
rpgDB.execSQL("CREATE TABLE IF NOT EXISTS " + classTable + " (classID INT(3), className TEXT, classHP INT(4));");
rpgDB.execSQL("INSERT INTO " + classTable + classFields + " VALUES (1, 'Warrior', 10);");
rpgDB.execSQL("INSERT INTO " + classTable + classFields + " VALUES (2, 'Rogue', 7);");
rpgDB.execSQL("INSERT INTO " + classTable + classFields + " VALUES (3, 'Mage', 5);");
String query = "SELECT className AS _id FROM " + classTable;
Cursor cursor = rpgDB.rawQuery(query, null);
rpgDB.close();
int[] to = new int[] { R.id.classDropDown };
String[] spinnerFields = new String[] { "_id" };
/**
* Test code to check value of cursor
*/
int count = cursor.getCount();
cursor.moveToFirst();
while (cursor.isAfterLast() == false)
{
String test = cursor.getString(0);
cursor.moveToNext();
}
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.main, cursor, spinnerFields, to);
int cursorcount = cursorAdapter.getCount();
// cursorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner classDropDown = (Spinner) this.findViewById(R.id.classDropDown);
classDropDown.setAdapter(cursorAdapter);
} catch (Exception ex) {
System.out.println("Exception: " + ex);
}
Populating a Spinner from a SimpleCursorAdapter seems to be ridiculously troublesome.
EDIT: The error with this code is
Invalid statement in fill window
If I comment out the rpgDB.close() line
Spinner is not a view that can be bounds by this SimpleCursorAdapter
If I change the select statement and spinnerfields to (with the DB commented out):
String query = "SELECT className FROM " + classTable;
String[] spinnerFields = new String[] { "className" };
I get:
column '_id' does not exist
EDIT XML: Here is the main.xml (also id main) XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#color/white" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="11pt"
android:text="#string/hello"
android:textColor="#color/baseTextColor" />
<Spinner
android:id="#+id/classDropDown"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
EXPLANATION: So if anyone comes upon this in the future, thanks to Luksprog, I understand this a bit better (and he showed me the fixes):
The android.R.id and android.R.layout "ids/layouts" are default xml layouts for Android components such as a TextField and Spinner "list" layouts. The Spinner object is basically NOT complete on its own. You need another XML portion to define how the list itself looks and another one for the lines (the text1 is a default android TextField).
So in short, assign your "to" field to a TextField or use one of the default Android ones such as android.id.text1, but in order to use that I believe you also have to use the layout that CONTAINS the default android field, andoid.R.layout (in my case, simple_spinner_item). Lastly, set the dropdownresource to your own xml or an android default (mine was android.R.layout.simple_spinner_dropdown_item).
Check this:
String query = "SELECT _id, className FROM " + classTable;
Cursor cursor = rpgDB.rawQuery(query, null);
int[] to = new int[] { android.R.id.text1 };
String[] spinnerFields = new String[] { "className"};
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_spinner, cursor, spinnerFields, to);
cursorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner classDropDown = (Spinner) this.findViewById(R.id.classDropDown);
classDropDown.setAdapter(cursorAdapter);
Invalid statement in fill window
You can't close the database connection if you want to pull data from that Cursor.
Spinner is not a view that can be bounds by this SimpleCursorAdapter
The to int array represents the ids of the Views from the row layout file that you pass to the SimpleCursorAdapter to bind data from the from array (R.layout.main, I hope that you do have a layout file and just pass the activity's layout). The id R.id.classDropDown that you used there represents a Spinner view and a SimpleCursorAdapter doesn't know how to bind data to that(it can bind data to a TextView or ImageView). If you want a Spinner on each row(do you really want this? or do you want the default spinner row layout?) then use a custom adapter or a SimpleCursorAdapter.ViewBinder.
column '_id' does not exist
Because you don't have a column with this name in the table classTable. This column should be declared like:
INTEGER PRIMARY KEY AUTOINCREMENT
Maybe you can check this simple tutorial for Spinners.

ListView has correct number of rows, but shows no text

I have created a ListActivity inside a tabhost, and this tab is supposed to show all records from a sql table. When I click the tab however, it shows the right amount of rows (separation lines) but there's no data/text anything else to be seen. So basically I get an empty list, and I've checked the database file, the data is there!
My table only has the columns _id and name.
This is the code I'm using:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor c;
ShowAdapter sa = new ShowAdapter(this);
sa.open();
c = sa.getSubscribedShows();
String[] from = new String[] { "name" };
int to[] = new int[] { R.id.text1 };
SimpleCursorAdapter shows = new SimpleCursorAdapter(this, R.layout.show_list, c, from, to);
setListAdapter(shows);
sa.close();
}
And my other method simply returns the cursor:
public Cursor getSubscribedShows(){
Cursor c = db.query(true, "shows", null, null, null, null, null, "name", null);
c.moveToFirst();
return c;
}
And my XML is:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:id="#+id/text1" >
</TextView>
Any ideas what I'm doing wrong?
Change the layout_height propery to:
android:layout_height="wrap_content"
and see if that fixes it

Begginner working with ListAdapters / SQLite Database

My programming knowledge is slim, i discovered Java and the Android SDK some days ago.
I have a SQLiteDatabase, a SQLiteOpenHelper, and a Cursor working properly
( means i think i understood how to create/open a DB using a SQLiteOpenHelper, make queries on my DB and get a cursor )
currently, i'm wrapping i + labName + labCity into a single results String, and display into a single TextView R.id.label
Is it possible to bind labName to R.id.label, and bind labCity to another TextView R.id.label2 ?
Here is the code of my ListActivity i need help with :
public class MainLabList extends ListActivity implements OnItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_lab_list);
// DB
GestionDB gdb = new GestionDB(this, GestionDB.DATABASE_NAME, null, GestionDB.DATABASE_VERSION);
SQLiteDatabase theDB = gdb.getWritableDatabase();
// Cursor
String[] columns = {GestionDB.LAB_NAME, GestionDB.LAB_ADDRESS_CITY};
Cursor c =
theDB.query(GestionDB.TABLE_NAME, columns, null, null, null, null, null);
////////
this.setTitle(" " + c.getCount() + " Labs in Local Database");
ArrayList<String> results = new ArrayList<String>();
int i = 0;
c.moveToFirst();
/* Loop through all Results */
do {
i++;
String labName = c.getString(c.getColumnIndex(GestionDB.LAB_NAME));
String labCity = c.getString(c.getColumnIndex(GestionDB.LAB_ADDRESS_CITY));
/* Add current Entry to results. */
results.add("" + i + ": " + labName
+ " (" + labCity + ")");
} while (c.moveToNext());
//need rework
ListView lvLabListing = (ListView) findViewById(android.R.id.list);
ArrayAdapter<String> labListAdapter = new ArrayAdapter<String>(this,
R.layout.listing, R.id.label, results );
lvLabListing.setAdapter(labListAdapter);
lvLabListing.setOnItemClickListener(this);
//
// don't forget to close the database
gdb.close();
And the listing.xml i would like to modify :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:layout_width="fill_parent">
<ImageView android:id="#+id/ImageView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="#drawable/icon"></ImageView>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/label"></TextView>
</LinearLayout>
My GestionDB class is simple, just define some columns if the database doesn't exist, along with some variables.
You should use a CursorAdapter, perhaps a SimpleCursorAdapter, for this. Here is an example.

Categories

Resources