Android Listview Fill from SQL with loop - android

I trying to populate a listview with data from an SQL database using the following code
final DBAdapter db = new DBAdapter(this);
db.open();
Cursor c = db.getAsset6("MARK BARR");
int mx=1;
String[] lvdata = new String[mx];
while (c.moveToNext()) {
lvdata[mx]=c.getString(1) + "-" + c.getString(2) + "-" + c.getString(6);
mx++;
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, lvdata));
getListView().setTextFilterEnabled(true);
db.close();
When I run the app crashes I'm am sure it something to do with the way i'm adding the data into a string in the while loop and then setting the adapter but I cant work out where I'm going wrong
Any help is appreciated
Mark
EDIT
OK the following works OK now But he app crashed when I reach the last listview entry
final DBAdapter db = new DBAdapter(this);
db.open();
Cursor c = db.getAsset6("MARK BARR");
int mx=0;
String[] lvdata = new String[c.getCount()];
while (c.moveToNext()) {
lvdata[mx]=c.getString(1) + "-" + c.getString(2) + "-" + c.getString(6);
mx++;
}
// use your custom layout
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.rowlayout, R.id.label, lvdata);
setListAdapter(adapter);
}

Well I am probably not worthy of even tying Vogella's shoes but this how I do it. I like using CursorAdapter because it allows you do all kinds of things with images and I think it's easier. If if you don't use this please check it out as you may need this in the future. Put this where you want to view the data whether in onCreate or from some button being pushed.
SQLiteDatabase sqLiteDatabase = controller.getReadableDatabase();
String query = "SELECT DISTINCT * FROM YOURTABLENAME";
Cursor cursor = sqLiteDatabase.rawQuery(query, null);
((ListView) YOURLISTVIEWNAME).setAdapter(new ANYNAMEADAPTER(context,
cursor, 0));
Then we create ANYNAMEADAPTER to get all the data into one organized place
private static final class ANYNAMEADAPTER extends CursorAdapter {
ANYNAMEADAPTER(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
mInflater = LayoutInflater.from(context);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
return v;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView theline = (TextView) view.findViewById(android.R.id.text1);
String thedata =cursor.getString(1) + "-" + cursor.getString(2) + "-" + cursor.getString(6);
theline.setText(thedata);
}
LayoutInflater mInflater;
}

Related

SQLite with CursorAdapter to Custom ListView

How fill Custom ListView with Data from SQLite database?
Which type of Adapter I should use?
screenshot http://www.codelearn.org/android-tutorial/assets/list_view/Custom_Base_adapter-6c6a43148474a723639fcbb8c85f5786.png
If you want to do ListView with Data from SQLite try use CursorAdapter.
ListAdapter.java
public class ListAdapter extends CursorAdapter {
public ListAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, 0);
}
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
return LayoutInflater.from(context).inflate(R.layout.items, parent, false);
}
// The bindView method is used to bind all data to a given view
#Override
public void bindView(View view, Context context, final Cursor cursor) {
TextView txt1 = (TextView) view.findViewById(R.id.TitleLabel);
TextView txt2 = (TextView) view.findViewById(R.id.SecondLabel);
TextView txt3 = (TextView) view.findViewById(R.id.ThirdLabel);
// Extract properties from cursor
// getString(int) - number of column
String value1 = cursor.getString(1);
String value2 = cursor.getString(2);
String value3 = cursor.getString(3);
String value4 = cursor.getString(4);
txt1.setText(value1);
txt2.setText("value2: " + value2);
txt3.setText("value3: " + value3 + "value4: " + value4);
}
}
MainActivity.java
helper - Database helper class
ListView listview = (ListView) findViewById(R.id.listView);
SQLiteDatabase db = helper.getWritableDatabase();
final Cursor ListCursor = db.rawQuery("SELECT * FROM tablename", null);
final ListAdapter todoAdapter = new ListAdapter(this, ListCursor, 0);
// Attach cursor adapter to the ListView
listview.setAdapter(todoAdapter);
If you want to display single field in listview then use simple Arrayadapter i.e.
DBHelper mydb = new DBHelper(this);
ArrayList array_list = mydb.getAllCotacts();
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1, array_list);
ListView obj = (ListView)findViewById(R.id.listView1);
obj.setAdapter(arrayAdapter);
other wise implement custom adapter extends with BaseAdapter.

Android: Updating ListView

Well, I have read almost 50 links related to this question, but my code still not working.
I have a Custom adapter which extends SimpleCursorAdapter class, and I use that adapter to fill the ListView on onCreate method
private void populateListView()
{
String[] from = new String[] { SchemaHelper.TASK_DESCRIPTION, SchemaHelper.TASK_CREATED_ON, SchemaHelper.TASK_ID };
int[] to = new int[] {R.id.lv_row_description, R.id.lv_row_created_on};
tasksCursor = schemaHelper.getTasks();
startManagingCursor(tasksCursor);
tasksAdapter = new TasksAdapter(this, R.layout.tasks_listview_row, tasksCursor, from, to);
setListAdapter(tasksAdapter);
}
The App is a simple task manager, I want to update the ListView contents when the user submits a new task without calling setListAdapter() again.
I have tried notifyDataSetChanged (running on ui thread), invalidate, requery(deprecated)... almost everything.
I'm doing something wrong?
EDIT:
This is the method where I add a new task to the database
private void addTask(String description)
{
String message = "";
schemaHelper.open();
if(schemaHelper.isAlreadyInDatabase(description))
{
message = getString(R.string.task_already_exists);
}
else
{
message = getString(R.string.task_succesfully_added);
schemaHelper.insertTask(description);
populateListView();
newTask.setText("");
}
schemaHelper.close();
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
ADAPTER CLASS:
private class TasksAdapter extends SimpleCursorAdapter
{
private LayoutInflater layoutInflater;
private Cursor cursor;
public TasksAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
{
super(context, layout, c, from, to);
cursor = c;
cursor.moveToFirst();
layoutInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if(cursor.getPosition() < 0)
{
cursor.moveToFirst();
}
else
{
cursor.moveToPosition(position); // Here throws the error
}
View row = layoutInflater.inflate(R.layout.tasks_listview_row, null);
TextView description = (TextView) row.findViewById(R.id.lv_row_description);
TextView createdOn = (TextView) row.findViewById(R.id.lv_row_created_on);
description.setText(cursor.getString(cursor.getColumnIndexOrThrow(SchemaHelper.TASK_DESCRIPTION)));
createdOn.setText(getString(R.string.added_on) + " " + TaskHelper.formatDateWithSuffix(cursor.getString(cursor.getColumnIndexOrThrow(SchemaHelper.TASK_CREATED_ON))));
return row;
}
}
i dont know much of the taskCursor and taskAdapter but i used ArrayAdapter i guess, well have a look in my code and take your own conclusions.
//LISTVIEW database CONTATO
ListView user = (ListView) findViewById(R.id.lvShowContatos);
//String = simple value ||| String[] = multiple values/columns
String[] campos = new String[] {"nome", "telefone"};
list = new ArrayList<String>();
Cursor c = db.query( "contatos", campos, null, null, null, null, "nome" + " ASC ");
c.moveToFirst();
String lista = "";
if(c.getCount() > 0) {
while(true) {
list.add(c.getString(c.getColumnIndex("nome")).toString());
if(!c.moveToNext()) break;
}
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, list);
user.setAdapter(adapter);
If you don't want to use requery() you can simply pass a new Cursor with the same query:
tasksCursor.close();
tasksCursor = schemaHelper.getTasks();
startManagingCursor(tasksCursor);
tasksAdapter.changeCursor(tasksCursor);
I assume that when you call addTask() you have already called populateListView() once. Try changing addTask() to this:
private void addTask(String description)
{
String message = "";
schemaHelper.open();
if(schemaHelper.isAlreadyInDatabase(description))
{
message = getString(R.string.task_already_exists);
}
else
{
message = getString(R.string.task_succesfully_added);
schemaHelper.insertTask(description);
// Remove call to populateListView(), just update the Cursor
tasksCursor.close();
tasksCursor = schemaHelper.getTasks();
startManagingCursor(tasksCursor);
tasksAdapter.changeCursor(tasksCursor);
newTask.setText("");
}
schemaHelper.close();
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
If this "doesn't work", please be more specific. Is it throwing an error, if so what kind?
You are doing a little too much work in your adapter. Please watch Android's Romain Guy at Google Talks discuss adapters and getView(). However since you only want to pass one special string to your createdOn TextView, let's do something very different and override setViewText():
Try this:
public class TasksAdapter extends SimpleCursorAdapter {
String prefix;
public TasksAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to) {
super(context, layout, cursor, from, to);
// This is constant so set it once and consider adding the space to the end of the String in strings.xml
prefix = getString(R.string.added_on) + " ";
}
#Override
public void setViewText(TextView v, String text) {
if(v.getId() == R.id.lv_row_created_on)
v.setText(prefix + TaskHelper.formatDateWithSuffix(text));
else
super.setViewText(v, text);
}
}
The rest of the data is taken care of with SimpleCursorAdapter's existing methods.

couple questions about custom arrayadapter

so im a little confused here....
i have code that takes info from my sqlite database and populates a list, then shows the list using the standard array adapter. what i want to do is have it so that in this list, the row color is green if the "completed" table row value is "yes"
heres my db structure for the table being used:
String CREATE_ACHIEVEMENTS_TABLE = "CREATE TABLE achievements ("
+ "id INTEGER PRIMARY KEY,"
+ "name VARCHAR,"
+ "type VARCHAR,"
+ "value VARCHAR,"
+ "completed VARCHAR"
+ ")";
heres my code that gets the list from the db:
public ArrayList<String> getAchievements(Context context) {
ArrayList<String> achievementList = new ArrayList<String>();
String selectQuery = "SELECT * FROM achievements ORDER BY id asc";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
if (cursor.getString(4).equals("yes")) {
achievementList.add(cursor.getString(1)+" (completed)");
}
else {
achievementList.add(cursor.getString(1));
}
} while (cursor.moveToNext());
}
}
else {
achievementList.add(context.getResources().getString(R.string.na));
}
cursor.close();
db.close();
return achievementList;
}
heres my custom arrayadapter:
public class AchievementAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public AchievementAdapter(Context context, String[] values) {
super(context, R.layout.achievements, values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.achievement_item, parent, false);
}
return row;
}
}
i really have no clue where to go from here. this is my first android app and i have learned a LOT, but i cant seem to figure out how to achieve this simple thing in regards to custom arrayadapters....all the tutorials i find contain a bunch of features that i dont want. all im trying to do is make the text color of the list item green if its "completed" table value is "yes"...
First of all, I recommend using a cursorAdapter instead of an arrayAdapter. With a cursor adapter you will have a pointer to the DB so you can get all of the information from there.
If you do that... your code for the adapter should look something like this.
private class MyCursorAdapter extends CursorAdapter {
public MyCursorAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public void bindView(View v, Context context, Cursor cursor) {
if(cursor.getString(cursor.getColumnIndex("completed").equals("yes")){
TextView tv = (TextView) v.findViewById(R.id.NAMEOFTEXTVIEW);
tv.setTextColor(Color.GREEN);
}
}
#Override
public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.achievement_item, parent, false);
return row;
}
}
and you create the adapter with:
Cursor cursor = db.rawQuery(selectQuery, null);
mAdapter = new MyCursorAdapter(this, cursor);
Having said all that... if you want to use the arrayAdapter and just change the textview,
in getView:
String item = (String) getItem(position);
if(item.contains("(completed)"){
TextView tv = (TextView) row.findViewById(R.id.NAMEOFTEXTVIEW);
tv.setTextColor(Color.GREEN);
}
I should note that with a cursorAdapter you should keep the cursor open, and close it in onStop (reopen it in onRestart)

Make listview from SQLite database

I'm trying to populate listview from my SQLite database... this is how I get my data from database:
Cursor c = database.rawQuery("SELECT * FROM " + TableName, null);
int Column1 = c.getColumnIndex("uri");
int Column2 = c.getColumnIndex("file");
int Column3 = c.getColumnIndex("id");
c.moveToFirst();
if (c != null) {
do {
String uri = c.getString(Column1);
String file = c.getString(Column2);
int id = c.getInt(Column3);
} while (c.moveToNext());
}
I would normally add an array to listview like that:
ListView my_listview2 = (ListView) findViewById(R.id.listView1);
String my_array[] = {"Android", "iPhone"};
my_listview2.setAdapter(new ArrayAdapter<String>(this, R.layout.row, R.id.my_custom_row, my_array));
How can I make an array to setadapter from my sql query?
The best way to do this is to use a CursorAdapter or a SimpleCursorAdapter. This will give you the best performance and once you figure it out you'll find it's the simplest approach when using a SQLite db.
http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html
Below is a simple CustomCursorAdapter that I use frequently. Just add the CustomCursorAdapter class as an inner class.
protected class CustomCursorAdapter extends SimpleCursorAdapter {
private int layout;
private LayoutInflater inflater;
private Context context;
public CustomCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.layout = layout;
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
Log.i("NewView", newViewCount.toString());
View v = inflater.inflate(R.layout.list_cell, parent, false);
return v;
}
#Override
public void bindView(View v, Context context, Cursor c) {
//1 is the column where you're getting your data from
String name = c.getString(1);
/**
* Next set the name of the entry.
*/
TextView name_text = (TextView) v.findViewById(R.id.textView);
if (name_text != null) {
name_text.setText(name);
}
}
Create an instance of the CustomCursorAdapter like so...
You'll need to create your cursor just like you're already doing.
protected String[] from;
protected int[] to;
//From is the column name in your cursor where you're getting the data
//to is the id of the view it will map to
from = new String[]{"name"};
to = new int[]{R.id.textView};
CustomCursorAdapter adapter = new CustomCursorAdapter(this, R.layout.list, cursor, from, to);
listView.setAdapter(adapter);
I found working with the notepad tutorial very useful for learning about this.
It shows you how to implement the listview using the sqlite database in very easy steps.
http://developer.android.com/resources/tutorials/notepad/index.html

Strange behaviour with custom cursor adapter android

i have been having this issue for some time now, and have not gotten an answer for it yet. i have this custom Cursor adapter which i use to populate a list view from an sqlite database. Now my issue is that i want to populate the listview based on certain conditions.An example is if the condition is important, the listview should display only data that fits into that criteria and so on. I already have working methods that query the database accordingly.
now my problem is that, i can't seem to populate the listviews based on those methods and conditions without:
1) creating a copy of the exact same custom cursor adapter and just changing the names variables.
2) creating a copy of the exact xml layout and changing the id's.
As i say, its working this way, but i feel am having unnecessary classes and xml layout since its exactly the same thing. I know am doing something wrong, i just don't know what. Please any help and explanation would be appreciated. here is the necessary part of the code Code for the CustomCursorAdapter:
public class ViewItems extends ListActivity implements OnItemClickListener{
DBAdapter adapter;
Cursor cursor;
ListView list;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_list);
adapter = new DBAdapter(this);
adapter.open();
fillData();
list = (ListView)findViewById(android.R.id.list); // default android listView id
list.setOnItemClickListener(this);
}
// Different method calls
protected void fillImportantData() {
Cursor cursor = adapter.retrieveImportant();
startManagingCursor(cursor);
String[] from = new String[]{DBAdapter.NAME, DBAdapter.DATE, DBAdapter.TIME, DBAdapter.PRIORITY};
int[] to = new int[]{R.id.viewNameId, R.id.viewDateId, R.id.viewTimeId};
customCursorAdapter items = new customCursorAdapter(this, R.layout.view_items, cursor, from, to);
setListAdapter(items);
}
public class customCursorAdapter extends SimpleCursorAdapter {
private int layout;
Context context;
public customCursorAdapter(Context context, int layout, Cursor cursor, String[]from, int[] to) {
super(context, layout, cursor, from, to);
this.layout = layout;
this.context = context;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder;
if(view != null){
holder = new ViewHolder();
holder.viewName = (TextView)view.findViewById(R.id.viewNameId);
holder.viewStartDate = (TextView)view.findViewById(R.id.viewDateId);
holder.viewStartTime = (TextView)view.findViewById(R.id.viewTimeId);
view.setTag(holder);
}else{
holder = (ViewHolder)view.getTag();
}
int namecol = cursor.getColumnIndex(DBAdapter.NAME);
String name = cursor.getString(namecol);
if(holder.viewName != null){
holder.viewName.setText(name);
holder.viewName.setTextColor(Color.RED);
}
String startDate = cursor.getString(cursor.getColumnIndex(DBAdapter.DATE));
holder.viewStartDate.setText(startDate);
String startTime = cursor.getString(cursor.getColumnIndex(DBAdapter.TIME));
holder.viewStartTime.setText(startTime);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
final View view = inflater.inflate(layout, parent, false);
return view;
}
#Override
public long getItemId(int id){
return id;
}
#Override
public Object getItem(int position){
return position;
}
}
static class ViewHolder{
TextView viewName;
TextView viewStartDate;
TextView viewStartTime;
}
}
// methods in database
public Cursor retrieveAll(){
String[] resultColumns = new String[] {KEY_ID, NAME DATE, TIME, PRIORITY};
Cursor cursor = db.query(DATABASE_TABLE, resultColumns, null, , null, null, null);
return cursor;
}
public Cursor retrieveImportant(){
String[] resultColumns = new String[] {KEY_ID, NAME DATE, TIME, PRIORITY};
String[] condition = {"important"};
Cursor cursor = db.query(DATABASE_TABLE, resultColumns, PRIORITY + "=" + "?", condition, null, null, null);
return cursor;
}
If you change the data you wish to display, you will need to run a fresh query on the database and get a Cursor back that reflects that changed data. Depending on the nature of the changes, this may require a fresh CursorAdapter or merely a call to changeCursor(). If the new query returns the same columns and you want them displayed the same way, changeCursor() is probably sufficient. Otherwise, you will need to create a new CursorAdapter and call setAdapter() on your ListView to switch over to it.
You only need a different row layout if you are truly changing the row layout. You do not need to change IDs just for grins. Since you are not doing this in the code you have shown above, I am unclear what specifically you are worried about.

Categories

Resources