i can add to a db and list as a listview.
When I click a list item using onListItemClick, what statement do I
need to get the value?
Thanks in advance.
public class Main extends ListActivity {
private static String[] FROM = { _ID, DESCRIPTION, UN };
private static String ORDER_BY = DESCRIPTION + " ASC";
private static int[] TO = {R.id.itemrowid, R.id.itemdescription, R.id.itemun };
private EventsData events;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
events = new EventsData(this);
try {
Cursor cursor = getEvents();
showEvents(cursor);
} finally {
events.close();
}
**public void onListItemClick(ListView parent, View v, int position, long id) {
// What statement to put here to get the value of _ID,DESCRIPTION, UN
// selected**?
}
private Cursor getEvents() {
// Perform a managed query. The Activity will handle closing
// and re-querying the cursor when needed.
SQLiteDatabase db = events.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null,
null, ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
private void showEvents(Cursor cursor) {
// Set up data binding
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.item, cursor, FROM, TO);
setListAdapter(adapter);
}
First, you need to obtain item at clicked position:
Cursor cursor = getListAdapter().getItem(position);
Then you can get data from this cursor (I don't know what types do you use, so just for example it will be int and String):
int id = cursor.getInt(cursor.getColumnIndex(_ID));
String description = cursor.getString(cursor.getColumnIndex(DESCRIPTION));
See documentation for Cursor's available methods.
Adding to sergey answer you can also directly see what View was clicked and use findViewById() to find the components, therefore, the values you want.
This is just an alternative being the method Sergey much less 'patchy'
Related
I have created a ListView using CursorAdapter . Now I am Trying to update the ListView and Refresh the value to the ListView .
But I am not able to figure out . How to work with Loader or changeCursor() to refresh my ListView
Below is My code of setting the CursorAdapter :
//SucessFully done here
SQLDataSore datastore = new SQLDataSore(PrintContent.this);
Cursor cursor = datastore.getJSONData();
final CursorDemo cursorDemo = new CursorDemo(PrintContent.this, cursor);
list_View.setAdapter(cursorDemo);
My Button onClick I am updating the Value into the Database
//SucessFully Done
btn_check.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View view ) {
String editTextValue = edit_check.getText().toString();
if (editTextValue!=null) {
SQLDataSore sqlDataSore = new SQLDataSore(PrintContent.this);
Cursor cursor_update = sqlDataSore.updateData(editTextValue);
//Here How Should I update my ListView ...?
}
}
My UpdateData Method:
public Cursor updateData(String editContent){
SQLiteDatabase updateContent = getReadableDatabase();
Cursor cursor_update = updateContent.rawQuery( "update " +TABLE_NAME + " set content = '"+ editContent
+"' "+" where _id = 357", null);
return cursor_update;
}
CursorDemo Class
public class CursorDemo extends CursorAdapter{
public CursorDemo(Context context, Cursor c) {
super(context, c , false);
// TODO Auto-generated constructor stub
}
#Override
public void changeCursor(Cursor cursor) {
// TODO Auto-generated method stub
super.changeCursor(cursor);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
TextView txt_content = (TextView) view.findViewById(R.id.txt_content);
TextView txt_likes_count = (TextView) view.findViewById(R.id.txt_likescount);
TextView txt_name = (TextView) view.findViewById(R.id.txt_name);
TextView txt_display_name = (TextView) view.findViewById(R.id.txt_display_name);
txt_content.setText(cursor.getString(cursor.getColumnIndex("content")));
}
#Override
public View newView(Context context , Cursor cursor, ViewGroup viewGroup) {
// TODO Auto-generated method stub
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.message_row_view, viewGroup ,false);
return view;
}
}
Any Help is Appreciated...
});
If CursorDemo extends CursorAdapter, then you have to use adapter.swapCursor(cursor_update);
That should swap the old cursor out for the new one and reload the data. With swapCursor, the old cursor is not closed.
In your CursorDemo you have to owerwrite changeCursor() method and reset the Cursor if you have indexer you have to set it's cursor too.
#Override
public void changeCursor(Cursor cursor) {
mIndexer.setCursor(cursor);
super.changeCursor(cursor);
}
public void changeCursor (Cursor cursor)
Added in API level 1 Change the underlying cursor to a new cursor. If
there is an existing cursor it will be closed.
Parameters cursor The new cursor to be used
Also try for below method if it's apt for your requirement.
Set a FilterQueryProviderand pass your key to that filter.
final Cursor oldCursor = adapter.getCursor();
adapter.setFilterQueryProvider(myQueryProvider);
adapter.getFilter().filter(editTextValue, new FilterListener() {
public void onFilterComplete(int count) {
// assuming your activity manages the Cursor
// (which is a recommended way)
stopManagingCursor(oldCursor);
final Cursor newCursor = adapter.getCursor();
startManagingCursor(newCursor);
// safely close the oldCursor
if (oldCursor != null && !oldCursor.isClosed()) {
oldCursor.close();
}
}
});
private FilterQueryProvider myQueryProvider = new FilterQueryProvider() {
public Cursor runQuery(CharSequence searchKey) {
// assuming you have your custom DBHelper instance
// ready to execute the DB request
return sqlDataSore.updateData(searchKey);;
}
};
PS : The Cursor must include a column named _id or this class will not work see this.
btn_check.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View view ) {
String editTextValue = edit_check.getText().toString();
if (editTextValue!=null) {
SQLDataSore sqlDataSore = new SQLDataSore(PrintContent.this);
Cursor cursor_update = sqlDataSore.updateData(editTextValue);
cursorDemo.swapCursor(cursor_update);
//or cursorDemo=new CursorDemo(this,cursor_update);
list_View.setAdapter(cursorDemo);
}
}
Put this on the activity where declare the ListView . Just create a new adapter and put it in new cursor then recreate it or swap the cursor. make sure your listview or adapter not constant.
you could call
adapter.notifyDataSetChanged();
".java.lang.IllegalArgumentException: column '_id' does not exist ...althouh I have _id field in to my db table" means that the value of "cursor" in your code is wrong.
Check the code of getting the value of "cursor" please. A cursor must have a column named '_id'。
This is my suggestion
If you want to adapt/replace new cursor value to your list view , you should remove the old cursor from adapter and add new cursor value to the adapter.And finally adapt this adapter to listview using listview.setadapter(CursorAdapter) as follows.
liveTagListCursor = ctx.getContentResolver().query(
LiveTagProvider.TAG_LIST_URI, null, null, null, null);
tagCursorAdapter = new LiveTagListCursorAdapter(getActivity(),
liveTagListCursor);
tagCursorAdapter.swapCursor(liveTagListCursor);
listview.setAdapter(tagCursorAdapter);
My ListView currently is able to display only one column data. I want it to display two column data.
Here is the code for my ListView:
public class ProjectExplorer extends ListActivity {
private projectdatabase database;
protected Cursor cursor;
protected ListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = new projectdatabase(ProjectExplorer.this);
getinfo();
}
private void getinfo() {
database.open();
cursor = database.getDataforDisplay();
adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, new String[] {"project_name"}, new int[] { android.R.id.text1 }, 0);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView parent, View view, int position, long id) {
super.onListItemClick(parent, view, position, id);
Cursor c = ((SimpleCursorAdapter)parent.getAdapter()).getCursor();
c.moveToPosition(position);
// get project name here
String str_projectname= c.getString(c.getColumnIndex("project_name"));
Toast.makeText(this, str_projectname, Toast.LENGTH_LONG).show();
}
Here is the method in database class which return the cursor:
public Cursor getDataforDisplay () {
String[] columns = new String[] {KEY_ROWID, PROJECT_NAME, PROJECT_FINISH_DATE, PROJECT_DIFFICULTY, PROJECT_STATUS};
Cursor c = projectDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
projectDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
c.moveToFirst();
return c;
}
I also want to display KEY_ROWID which is defined as _id
You can use android.R.layout.simple_list_item_2 specifying column no.2 from table from where data can be retrieved and specifies location with help of it can be displayed on Activity - android.R.id.text2
adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, new String[] {"project_name","column_no2"}, new int[] { android.R.id.text1, andriod.R.id.text2 }, 0);
You can also create your on custom Adapter specifying your own Listview and creating it from scratch and customized everything.
The best way to achieve this at least in my opinion is to create custom Adapter for your ListView in that case you can set your own design how single listview element should look like . Just populate some arrays using your Cursor and set them to your custom adapter.
I can show the id, title and borrowed values in a TextView. My problem is that I would like to check the "borrowed" values, and if they are not null, display a simple image. If the value is null, I don't want to display anything.
Might work with a ViewBinder, but I don't know how to solve this.
private static String[] FROM = { _ID, TITLE, BORROWED };
private static String[] TO = { R.id.id, R.id.title, R.id.borrowed };
private Cursor getMovies() {
SQLiteDatabase db = movies.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null, null, ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
private void showTitles(Cursor cursor) {
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item, cursor, FROM, TO);
setListAdapter(adapter);
}
Extend your SimpleCursorAdapter and check for null of the BORROWED val in your overrided bindView() method. Something like this:
private class mySimpleCursorAdapter extends SimpleCursorAdapter{
#Override
public void bindView(View view, Context context, Cursor cursor) {
if ( cursor.isNull( cursor.getColumnIndex(BORROWED) ) ){
// Handle NULL scenario
} else {
// Handle not NULL scenario
}
}
}
This is not tested and there's other code you'll need to implement, but this is the idea.
You can apply where clause in db.query for non null values so that your cursor only has not null rows..
I am using SimpleCursorAdapter and database table to populate a List. The list gets populated and I am able to click on list items to open the desired item(This starts a new activity). The problem is when I press the back key, I got Following error.
IllegalStateException: database already closed.
My code is as follows:
public class populatingLectures extends ListActivity{
private static String[] FROM = {SUBJECT, TOPIC, LECTURENUMBER, DATE };
private static int[] TO = {R.id.subject, R.id.topic,
R.id.lecturenumber, R.id.date };
private static String[] data = { SUBJECT, TOPIC, LECTURENUMBER, _DATA };
private static String ORDER_BY = DATE + " DESC";
private SoftCopyDatabase lectures;
String gotId;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SoftCopyDatabase lectures = new SoftCopyDatabase(this);
try {
Cursor cursor = getLectures();
showLectures(cursor);
} finally {
lectures.close();
}
}
public void onStart() {
super.onStart();
lectures = new SoftCopyDatabase(this);
try {
Cursor cursor = getLectures();
showLectures(cursor);
} finally {
lectures.close();
}
}
private Cursor getLectures() {
SQLiteDatabase db = lectures.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME,null, "subject=?", new String[] {OpenClick.subjectName}, null, null,
ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
private void showLectures(Cursor cursor) {
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.item_lectures, cursor, FROM, TO);
setListAdapter(adapter);
}
private Cursor getFileName(String ID) {
SQLiteDatabase db = lectures.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, data, "_ID=?",
new String[] { ID }, null, null, null);
startManagingCursor(cursor);
return cursor;
}
#Override
protected void onListItemClick(ListView listView, View view, int position,
long id) {
super.onListItemClick(listView, view, position, id);
//...CODE TO START NEW ACTIVITY
}
}
}
Kindly tell me what mistake am I doing. Because I am not closing the database explicitly any where.
Regards,
Waneya Iqbal.
finally
{
lectures.close();
}
I think this line gives the exception, so put it in onDestroy().
You're closing the database as soon as you populate the list. You should move the
lectures.close()
line from onStart() to onDestroy(), which will make sure your database gets closed when the activity is complete, rather than as soon as the list is populated.
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.