I have created a SimpleCursorAdapter. I would like a way to compare two rows.
lets say the columns are called realData pracData. If i want to compare two columns how would I write the statement to achieve this.
Below is my code for my SimpleCursorAdapter
db = new DBAdapter(this);
db.open();
// db.insertContact("how do you print hello world", "print 'hello world';", "print hello", "hello", 1);
// db.insertContact("what is x=2 and y=5", "5", "7", "2", 2);
db.close();
/*
* Open the same SQLite database
* and read all it's content.
*/
db = new DBAdapter(this);
db.open();
Cursor cursor = db.getAllContacts();
startManagingCursor(cursor);
String[] from = new String[]{DBAdapter.question, DBAdapter.possibleAnsOne};
int[] to = new int[]{R.id.label, R.id.TextView01};
SimpleCursorAdapter cursorAdapter =
new SimpleCursorAdapter(this, R.layout.row, cursor, from, to);
listContent.setAdapter(cursorAdapter);
db.close();
This is from the ArrayAdapter
if (s.startsWith("how do you print hello world") || s.startsWith("iPhone")
|| s.startsWith("Solaris")) {
imageView.setImageResource(R.drawable.plus);
I want to do something similar but compare two rows in my database.
public class MyAdapter extends SimpleCursorAdapter {
private Context context;
private int layout;
public MyAdapter(Context context, int layout, Cursor c, String[] from,
int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.layout = layout;
// TODO Auto-generated constructor stub
}
#Override
public void bindView(View v, Context context, Cursor c) {
// do your magic inhere :) the cursor will be at the correct row position
System.out.println("please select a cursor");
// int nameCol = c.getColumnIndex(People.NAME);
// ListView listContent = (ListView)findViewById(R.id.contentlist);
// ImageView imageView = (ImageView)findViewById(R.id.ImageView01);
int nameCol = c.getColumnIndex(DBAdapter.question);
System.out.println("What is the column index" +nameCol);
}
}
Extending the SimpleCursorAdapter and overriding bindView should work. I usually extend CursorAdapter, but try something à la
public class MyAdapter extends SimpleCursorAdapter {
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView label = view.findViewById(R.id.yourid);
// and then do something with cursor.getString(columnindex);
}
}
Related
I have a ListView which shows a bunsh of values from a SQLite table. First I used a SimpleCursorAdapter to fill the ListView based on a Cursor from an SQL query. I switched over to using a SimpleAdapter in stead because I had to manipulate/add data in the list before sending it over to the ListView.
Using the SimpleCursorAdapter the id returned from the ListView after tapping a row is the correct ID from the database table, but using a SimpleAdapter the id looks like its just generated by the ListView because it is the same as the position.
My table looks like this:
_id | col1 | col2 | col3
The method producing the cursor for the SimpleCursorAdapter looks like this:
public Cursor fetchDataAsCursor()
{
return db.query("table_name", new String[] { "_id", "col1", "col2"}, null, null, null, null, null);
}
The method filling in the ListView using SimpleCursorAdapter looks like this:
private void simpleFillData()
{
Cursor cursor = dbAdapter.fetchDataAsCursor();
startManagingCursor(cursor);
String[] from = new String[] {"col1", "col2"};
int[] to = new int[] {R.id.col1, R.id.col2};
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.list_row, cursor, from, to);
setListAdapter(notes);
}
This works fine as the id returned is ok in the following method:
protected void onListItemClick(ListView l, View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, DetailActivity.class);
i.putExtra("_id", id);
startActivityForResult(i, ACTIVITY_EDIT);
}
Now switching over to the SimpleAdapter.
The code for producing the List:
public ArrayList<HashMap<String, Object>> getList()
{
ArrayList <HashMap<String, Object>> list = new ArrayList();
c = fetchDataAsCursor();
c.moveToFirst();
for(int i = 0; i < c.getCount(); i++)
{
HashMap<String, Object> h = new HashMap<String, Object>();
h.put("_id", c.getLong(0));
h.put("col1", c.getString(1));
h.put("col2", c.getString(2));
//This is the extra column
h.put("extra", calculateSomeStuff(c.getString(1), c.getString(2));
list.add(h);
c.moveToNext();
}
return list;
}
And then for the method which fills the ListView:
private void fillData()
{
ArrayList<HashMap<String, Object>> list = dbAdapter.getList();
String[] from = new String[] {"col1", "col2", "extra"};
int[] to = new int[] {R.id.col1, R.id.col2, R.id.extra};
SimpleAdapter notes = new SimpleAdapter(this, list, R.layout.list_row, from, to);
setListAdapter(notes);
}
In this last method the ListView failes to pick up the _id value in the list. I would have guessed that it would do this automaticly as it does when using a SimpleCursorAdapter
Is there a way to manipulate the id of a row in a ListView to be sure that it has the same value as the _id key in the database table?
(All code examples is greatly simplified)
Edit:
I figured it out. I had to make my own subclass of SimpleAdapter which overrides public long getItemId(int position)
public class MyListAdapter extends SimpleAdapter
{
private final String ID = "_id";
public PunchListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
{
super(context, data, resource, from, to);
}
#Override
public long getItemId(int position)
{
Object o = getItem(position);
long id = position;
if(o instanceof Map)
{
Map m = (Map)o;
if(m.containsKey(ID))
{
o = m.get(ID);
if(o instanceof Long)
id = (Long)o;
}
}
return id;
}
}
That is bad way to work with cursor by using SimpleAdapter. You should implement CursorAdapter.
public class MyCursorAdapter extends CursorAdapter
{
LayoutInflater inflater;
public MyCursorAdapter(Context context, Cursor c) {
super(context, c);
inflater = LayoutInflater.from(context);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
//cursor is already setted to requared position, just get your column
TextView tv1 = (TextView)view.findViewById(R.id.textView1);
TextView tv2 = (TextView)view.findViewById(R.id.textView2);
tv1.setText(cursor.getString(1));
tv2.setText(cursor.getString(2));
viev.addOnClickListener(new OnClickListener{
public void onClick(View v){
...
cursor.getLong(0);
...
}
});
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return inflater.inflate(R.layout.my_raw_view, parent, false);
}
}
Than just set adapter to listview in your activity.
Cursor cursor = fetchDataAsCursor();
ListView myListView = (ListView)findViewById(R.id.my_list_view);
myListView.setAdapter(new MyCursorAdapter(this,cursot));
I have a listview which populates its content from SQLite Database.
Here's my code:
ListView listView = (ListView) findViewById(R.id.lstText);
listView.setOnItemClickListener(this);
listView.setAdapter(new MySimpleCursorAdapter(this, R.layout.listitems,
managedQuery(Uri.withAppendedPath(Provider.CONTENT_URI,
Database.Project.NAME), new String[] { BaseColumns._ID,
Database.Project.C_PROJECTTITLE,
Database.Project.C_SMALLIMAGE, Database.Project.C_PROJECTDESCRIPTION, Database.Project.C_ORGANIZATIONTITLE}, null, null, null),
new String[] { Database.Project.C_PROJECTTITLE,
Database.Project.C_SMALLIMAGE, Database.Project.C_PROJECTDESCRIPTION, Database.Project.C_ORGANIZATIONTITLE}, new int[] {
R.id.txt_title, R.id.image, R.id.txt_list_desc, R.id.txt_org}));
I want to put an extra String to some TextViews above when its displayed on the list. For example, I want to add a String with the word "from" on R.id.txt_org, before the populated String from the database which is Database.Project.C_ORGANIZATIONTITLE
Let's say the populated String is: New Organisation,
with an extra String "from" what will be displayed is: from New Organisation
Can anybody help me with that? Thank you very much.
EDITED:
FYI, this is my SimpleCursorAdapter method:
class MySimpleCursorAdapter extends SimpleCursorAdapter {
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
loader = new ImageLoader(context);
this.context = context;
}
Context context=null;
ImageLoader loader = null;
public void setViewImage(ImageView v, String value) {
v.setTag(value);
loader.DisplayImage(value, context, v);
}
}
Since you're already using a custom adapter, override the adapter's bindView() and newView() methods, rather than getView(). That way you will not have to manually deal with recycling the row's view.
Within these method you can get the data from the resulting Cursor and manipulate it before binding it to your row's view.
GetView Vs. BindView in a custom CursorAdapter?
How to override CursorAdapter bindView
//Edit: some more code below. Note that this is just a rough outline and by no means complete or tested.
class MySimpleCursorAdapter extends SimpleCursorAdapter {
private ImageLoader mLoader = null;
private LayoutInflater mInflater = null;
private int mBusinessNameIndex = -1;
private int mSmallImageIndex = -1;
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
mLoader = new ImageLoader(context);
mInflater = getLayoutInflater();
mBusinessNameIndex = c.getColumnIndexOrThrow(Database.Project.NAME);
mSmallImageIndex = c.getColumnIndexOrThrow(Database.Project.C_SMALLIMAGE);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(R.layout.row, null);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Get your views from 'view'
TextView someTextView = (TextView) view.findViewById(R.id.xxx);
ImageView someImageView = (ImageView) view.findViewById(R.id.yyy);
// Set the data
someTextView.setText("from " + cursor.getString(mBusinessNameIndex));
mLoader.DisplayImage(cursor.getString(mSmallImageIndex ), context, someImageView);
}
}
hi am using cursor adapter for my listview, my problems is when i put my application in background ,on retuning my screen is empty, in onresume i have open the database and creating cursor still i have the problem, how can i solve my problem ,pls help me .
searchCursor= dbReaderContact.rawQuery(query, null);
startManagingCursor(searchCursor);
String[] from=new String[] {ALDbAdapter.TITLE,DbAdapter.CATID,DbAdapter.LTID,DbAdapter.RK,DbAdapter.SUBTITLE};
int [] to=new int[] {R.layout.ctllist_item};
catSearchAdapter=new CategorySearchAdapter(context, R.layout.ctllist_item, searchCursor, from, to);
//////////////Adapter calss
public class CategorySearchAdapter extends SimpleCursorAdapter implements Filterable{
private Context context;
private int layout;
private ALDbAdapter dbadapter;
/**
* #param context
* #param layout
* #param c
* #param from
* #param to
*/
public CategorySearchAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.layout=layout;
this.context=context;
dbadapter=new ALDbAdapter(context);
try {
dbadapter.openAngiesListDb();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }
StringBuilder buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuilder();
buffer.append("UPPER(");
buffer.append("name");
buffer.append(") GLOB ?");
args = new String[] { constraint.toString().toUpperCase() + "*" };
}
Cursor c=null;
// c=dbadapter.getPartialNamesSearch(constraint.toString());
return c;
}
#Override
public void bindView(View v, Context context, Cursor c) {
TextView subTitle=(TextView)v.findViewById(R.id.ctlName);
TextView title=(TextView)v.findViewById(R.id.cltAssocationName);
ImageView imgIcon=(ImageView)v.findViewById(R.id.ctlLogo);
int subTitInd=c.getColumnIndex(ALDbAdapter.SUBTITLE);
int titInd=c.getColumnIndex(ALDbAdapter.TITLE);
int ltId=c.getColumnIndex(ALDbAdapter.LTID);
int ltype=c.getInt(ltId);
if(!c.getString(subTitInd).equalsIgnoreCase("")){
subTitle.setText(c.getString(subTitInd));
title.setText(c.getString(titInd));
}else{
subTitle.setText(c.getString(titInd));
}
if(ltype==1){
imgIcon.setImageResource(R.drawable.logo1);
}else if(ltype==2){
imgIcon.setImageResource(R.drawable.logo2);
}else{
imgIcon.setImageResource(R.drawable.logo3);
}
}
}
//On post i closed the cursor
///On Resume
searchCursor= dbReaderContact.rawQuery(query, null);
startManagingCursor(searchCursor);
You are talking about ListView and using SimpleCursorAdapter. Don't you think creating your own ArrayAdaptor isn't more efficient : you create a class of your own to hold the data you want from your DB request (iterate over your Cursor), then you populate an ArrayList of that class.
Then you give this ArrayList to a class which extens ArrayAdaptor. You should store the ArrayList in the ArrayAdaptor and override contructor and the public View getView(int position, View convertView, ViewGroup parent) method to create each view of your ListView.
You can google custom ListView (first result : http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/ ).
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
I am trying to create Custom Cursor adapter and attach it to my listview.
Though I am not yet there to create textboxes and set values inside my adapter,
my code currently throws a runtime exception when I try to call super(ctx, c);
What could be wrong? Searched all over the web & couldn't get it. Thanks in advance!
Custom Cursor adapter:
public class CustomCursorAdaptor extends CursorAdapter {
private Context context;
private int layout;
public CustomCursorAdaptor (Context ctx, int layout, Cursor c, String[] from, int[] to) {
super(ctx, c);
this.context = ctx;
this.layout = layout;
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return(new View(context));
}
#Override
public void bindView(View v, Context context, Cursor c) {
}
}
and my Activity:
public class DynamicScrollView extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context ctx=getBaseContext();
RelativeLayout newLayout=new RelativeLayout(ctx);
ListView lv=new ListView(ctx);
SQLiteDatabase db;
db = ctx.openOrCreateDatabase("TShow.db", SQLiteDatabase.OPEN_READONLY, null);
db.setVersion(1);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);
Cursor cur = db.query("control", new String[] {"id"}, "parent_id=2", null, null, null, null);
CustomCursorAdaptor adapter = new CustomCursorAdaptor(ctx, lv.getId(), cur, new String[] {"id"}, new int[] {2});
lv.setAdapter(adapter);
newLayout.addView(lv);
setContentView(newLayout);
}
}
I really don't know much about the base context, which you are passing to your CursorAdaptor here, but I understand that usually you should rather be using your Activity as the context. Activity is a subclass of Context, in case you did not know.
So, in stead of:
new CustomCursorAdaptor(ctx, lv.getId(), cur, new String[] {"id"}, new int[] {2});
... you could try:
new CustomCursorAdaptor(this, lv.getId(), cur, new String[] {"id"}, new int[] {2});
Cursor adapter expects to have a column _id which it uses as index. I added another column as _id in the select and it worked! Updated code:
Cursor cur = db.query("control", new String[] {"id as _id", "id"}, "parent_id=2", null, null, null, null);
I traced it back from the exception description which said: column '_id' does not exist
Thank you for the golden tip about the _id column which is needed for the ListView to work.
#dmg: you must not name your _id column with the (native)SQL 'AS' statement. Just add the '_id' column without changing it.