I have ListView which have items from a database.
My adapter is this:
Cursor cur = myDb.getCategories();
// Closing the cursor
// DEPRECATED!!
startManagingCursor(cur);
// Set up mapping from cursor to view fields
String[] fromFieldNames = new String[] { DBAdapter.KEY_ITEM_CAT };
int[] toViewIDs = new int[] { R.id.tvItemCat };
// Create adapter to map columns of DB to elements on UI
myCursorAdapter = new SimpleCursorAdapter(this, // Context
R.layout.category_layout, // Raw layout template
cur, // Cursor (set of DB records)
fromFieldNames, // DB column names
toViewIDs // views ID to putt in list view
);
// Set the adapter for list view
LVCat.setAdapter(myCursorAdapter);
getCategories():
Cursor c = db.rawQuery("SELECT DISTINCT " + KEY_ITEM_CAT + " as " + KEY_ITEM_ID
+ ", " + KEY_ITEM_CAT + " FROM " + ITEMS_TABLE_NAME, null);
if (c != null) {
c.moveToFirst();
}
return c;
I want when i click on some item I should get item name.
I've search and i found this code:
public void onCatClick(){
LVCat.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// TODO Auto-generated method stub
String category = LVCat.getItemAtPosition(position).toString();
// String category = parent.getItemAtPosition(position).toString(); --> This also I've tried, but the same result
System.out.println("Cat: " + category);
}
});
}
For other people this works. But I don't get the item name i get something like this:
System.out(23858): Cat: android.database.sqlite.SQLiteCursor#4197f3a0
So how can I get the selected item name?
Use parent.getItemAtPosition(position).toString() in your onItemClickListener to get item.
or use it
TextView tv = (TextView) v.findViewById(R.id.tvItemCat);
String value = tv.getText().toString();
Related
Right now, my app filters the data in a listview when somethings is entered into the editText, but it can only filter by one thing at a time. I want it to be able to filter by more than value. For example, if someone types in "chicken" it should filter the recipes by the word 'chicken'. But, if someone then types in "dinner", I want it to filter the recipes by both "chicken" and "dinner." Eventually, I want to make it so those values appear as checkboxes above the listview so they can be easily removed.
I can't figure out how to do this. I played around with loops at first but didn't really get anywhere.
public class SearchActivity extends NavDrawerActivity {
private DBHandler dbHelper;
private SimpleCursorAdapter dataAdapter;
ArrayList<String> filters = new ArrayList<String>();
//String[] filters;
FrameLayout frameLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main_activity3);
frameLayout = (FrameLayout) findViewById(R.id.activity_frame);
// inflate the custom activity layout
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View activityView = layoutInflater.inflate(R.layout.activity_main_activity3, null, false);
// add the custom layout of this activity to frame layout.
frameLayout.addView(activityView);
dbHelper = new DBHandler(this, null, null, 1);
//dbHelper.open();
//Clean all data
dbHelper.deleteAllRecipes();
//Add some data
dbHelper.insertSomeRecipes();
//Generate ListView from SQLite Database
displayListView();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
private void displayListView() {
final Cursor cursor = dbHelper.fetchAllRecipes();
// The desired columns to be bound
String[] columns = new String[]{
//DBHandler.COLUMN_CODE,
DBHandler.COLUMN_NAME,
DBHandler.COLUMN_TYPE,
DBHandler.COLUMN_INGRED
};
// the XML defined views which the data will be bound to
int[] to = new int[]{
//R.id.code,
R.id.name,
R.id.type,
R.id.ingredient,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
this, R.layout.recipeinfo,
cursor,
columns,
to,
0);
ListView listView = (ListView) findViewById(R.id.listView1);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
String recipeName = cursor.getString(cursor.getColumnIndexOrThrow("name"));
Intent n = new Intent(getApplicationContext(), RecipeActivity.class);
//n.putExtra("position", position);
n.putExtra("recipeName", recipeName);
startActivity(n);
}
});
//final GridView gridView = (GridView)findViewById(R.id.gridView);
final TextView tv = (TextView)findViewById(R.id.textView14);
final EditText myFilter = (EditText) findViewById(R.id.myFilter);
myFilter.setImeActionLabel("Filter",1);
myFilter.setPrivateImeOptions("actionUnspecified");
myFilter.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == 1 || id == EditorInfo.IME_NULL) {
String filter = textView.getText().toString();
dataAdapter.getFilter().filter(filter);
filters.add(filter);
tv.append(filter);
myFilter.setText("");
}
return false;
}
});
dataAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
return dbHelper.fetchRecipesByName(constraint.toString());
}
});
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Then you start a new Activity via Intent
Intent intent = new Intent();
intent.setClass(this, RecipeActivity.class);
intent.putExtra("position", position);
// Or / And
intent.putExtra("id", id);
startActivity(intent);
}
}
fetchRecipesByName in DBHandler
public Cursor fetchRecipesByName(String inputText) throws SQLException {
SQLiteDatabase mDb = this.getWritableDatabase();
Log.w(TAG, inputText);
Cursor mCursor = null;
if (inputText == null || inputText.length () == 0) {
mCursor = mDb.query(SQLITE_TABLE, new String[] {COLUMN_ROWID,
COLUMN_NAME, COLUMN_TYPE, COLUMN_INGRED, COLUMN_IMGPATH},
null, null, null, null, null);
}
else {
mCursor = mDb.query(true, SQLITE_TABLE, new String[] {COLUMN_ROWID,
COLUMN_NAME, COLUMN_TYPE, COLUMN_INGRED, COLUMN_IMGPATH},
COLUMN_NAME + " like '%" + inputText + "%'" + " or " +
COLUMN_TYPE + " like '%" + inputText + "%'" + " or " +
COLUMN_INGRED + " like '%" + inputText + "%'",
null, null, null, null, null);
}
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
What is the implementation of dbHelper.fetchReccipesByName()? I think, as of now, it queries the table only by one thing. You should change its logic and implement your complex need in this method (obviously, it should be an SQL query execution).
As a best practice, you should call listView.setFilterText() instead of dataAdapter.getFilter().filter(), because this method is supposed to run in secondary thread for the reason that DB queries are time consuming. If you call listView.setFilterText(), the framework will take care of threading and calls filter.filter() in secondary thread.
And finally, since you are searching by more than one keyword, but setFilterText() accepts only one CharSequence param, you should encode somehow many keywords into single String (say comma separated). And while querying you could decode the constraint to get the keywords.
How to create cursor object to get item id from database?
Here is my method of DBHelper, see the Cursor method
public int getItemIdByPosition(int position) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from " + TABLE_NAME, null);
cursor.moveToPosition(position);
return Integer.parseInt(cursor.getString(0));
}
Seems to be correct.
Maybe the position passed through method is not correct, maybe is more efficient is you use, instead of pass a position on your method pass the ID:
"select * from " + TABLE_NAME + " where id = " = id
Also you can use:
cursor.getColumnIndex(COLUMN_NAME) instead of cursor.getString(0)
Your code seems to be right, I just would check the below things that I mentioned.
String selectQuery = "SELECT * FROM " + TABLE_NAME + " WHERE " + POSITION + " = " + position;
db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
int userId;
if (cursor.moveToFirst())
{
userId = cursor.getInt(0);
}
cursor.close();
return userId;
This is a sample code hope you can get a help from this
private void displayListView(String getter){
//get the customer data from the db and feed them to cursor and load the data to lest
Cursor cursor = dbHelper.fetchallcustomercompany(getter);
String[] columns = new String[] {
//get the needed columns of the db and feed them in to string array
DBCreater.Key_customer_Shop
};
int[] to = new int[]{
//get the textboxs in xml layout,which going to display the values in to integer array
R.id.tv_demo_search_text_Isuru
};
//address the xml list view to java
final ListView listView = (ListView)findViewById(R.id.lv_searchcustomer_cuzlist_Isuru);
// feed the context,displaying layout,data of db, data source of the data and distination of the data
if(cursor.getCount()==0){
Toast.makeText(getApplicationContext(), " No matching data", Toast.LENGTH_SHORT).show();
}
else{
dataAdapter = new SimpleCursorAdapter(this, R.layout.demo_search, cursor, columns, to,0);
//load the data to list view
listView.setAdapter(dataAdapter);
//what happen on when user click on the item of the list view
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Cursor cursor =(Cursor)listView.getItemAtPosition(arg2);
//get the value of the customer name from the clicked listitem
String name=cursor.getString(cursor.getColumnIndexOrThrow("customer_shop"));
}
});
}
}
Try this:
public int getItemIdByPosition(int position) {
int itemID = 0;
Cursor localCursor = database.rawQuery("select * from " + TABLE_NAME,
null);
int i = localCursor.getColumnIndex("ID");
if (localCursor.moveToFirst()) {
do {
itemID = Integer.parseInt(localCursor.getString(i));
} while (localCursor.moveToPosition(position));
}
localCursor.close();
return itemID;
}
im a newbie to android and i have this problem here hope you guys can help me with this :)
anyways, i want to get the id of a selected item in the spinner from sqlite database so that i can save it to another table later on.
here's my code:
in my DB.java :
public List<String> getSemesterList() {
List<String> List = new ArrayList<String>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_SEMESTER;
Cursor c = ourDatabase.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (c.moveToFirst()) {
do {
List.add((c.getString(1)));
} while (c.moveToNext());
}
return List;
}
public String getSemesterId() {
String[] columns = new String[] { KEY_SEMESTER_ID, KEY_SEMESTER };
Cursor c = ourDatabase.query(TABLE_SEMESTER, columns, null, null, null, null, null, null);
int id = c.getColumnIndex(KEY_SEMESTER_ID);
String semId = "";
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
semId = semId + c.getInt(id) + " "
+ "\n";
}
return semId ;
}
and in my createSYAttended.class
// TODO Auto-generated method stub
DB entry = new DB(this);
entry.open();
final List<String> all = entry.getSemesterList();
if(all.size()>0) // check if list contains items.
{
sqlSem = (Spinner) findViewById(R.id.sprSemester);
arrayAdapter = new ArrayAdapter<String>(CreateSyAttended.this,android.R.layout.simple_spinner_dropdown_item, all);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sqlSem.setAdapter(arrayAdapter);
entry.close();
sqlSem.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
});
} }
use a mapping for the index of your List<String> all = entry.getSemesterList(); to the spinner item
so when you get below callback
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
you can then use the position you get in the callback to map to the item in the semesterList all
//function which is in my DatabaseHelper class which extends SQLiteOpenHelper
public String getCoordinatesLatitude(int id) {
String rowLat = "";
SQLiteDatabase db = this.getReadableDatabase();
String latQuery = "SELECT " + KEY_LATITUDE + "FROM " + TABLE_COORDINATES + "WHERE " + KEY_ID + "=" + id;
Cursor cursorr = db.rawQuery(latQuery,null);
if (cursorr != null){
cursorr.moveToPosition(id);
rowLat = cursorr.getString(cursorr.getColumnIndex(KEY_LATITUDE));
}
// return coordinates
return rowLat;
}
//function in my main activity
public void onListItemClick(ListView l, View v, int position, long id) {
selectedFromList = (String) (l.getItemAtPosition(position));
selectedItem = (int) l.getItemIdAtPosition(position);
String rowLat = helper.getCoordinatesLatitude(selectedItem);
Toast.makeText(getApplicationContext(), rowLat, Toast.LENGTH_SHORT).show();
}
I have a listview which contains locations. Each location contains latitude,longitude and a date. What i basically want is to click on a listview item, and retrieve the items latitude value from my database, based on its listview ID. I setup the getCoordinatesLatitude() function but i dont know if my code is correct, because when i click on a listview item i get force close and logcat shows nullPointerException. How can i make this work? Thanks
What my listview looks like
UPDATE!!!!
I managed to get rid of nullPointerException error, and changed my code to this
public String getLatitudeFromId(long id) {
String rowLat = "not found";
SQLiteDatabase db = this.getReadableDatabase();
//String latQuery = "SELECT " + KEY_LATITUDE + " FROM " + TABLE_COORDINATES + " WHERE " + KEY_ID + "=" + id;
//Cursor cursor = db.rawQuery(latQuery,null);
Cursor cursor = db.query(TABLE_COORDINATES, new String[] { "latitude" },"id="+id, null, null, null,null);
if (cursor.moveToFirst()){
cursor.moveToPosition((int) id);
rowLat = cursor.getString(cursor.getColumnIndex("latitude"));
}
cursor.close();
db.close();
// return coordinates
return rowLat;
}
and
public void onListItemClick(ListView l, View v, int position, long id) {
DatabaseHelper helper = new DatabaseHelper(this);
selectedFromList = (String) (l.getItemAtPosition(position));
selectedItem = l.getItemIdAtPosition(position);
String rowLat = helper.getLatitudeFromId(selectedItem);
Toast.makeText(getApplicationContext(), rowLat, Toast.LENGTH_SHORT).show();
}
But now, when i click on listview item, the toast is not found, so it stops in the if (cursor.moveToFirst()) statement because the cursor is empty. How can the cursor be empty when my listview is full of items? :P
UPDATE2
I fixed the problem just by changing my query to this Cursor cursor = db.query(TABLE_COORDINATES, new String[] {KEY_DATE}, null, null, null, null,null); where KEY_DATE is the column name that you want to be shown when u click an item in the listview
If the array which you have assigned to listview adapter is "array" then you can retrieve array.get(position).getLatitude(); (I assume you have use custom adapter)
First your table must have a column set as primary key named _id not id. Then you can pass to getLatitudeFromId the id you get from onItemClick.
Change getLatitudeFromId(long id) to this:
public String getLatitudeFromId(long id) {
String rowLat = "not found";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_COORDINATES, new String[] { "latitude" },"_id=" + id, null, null, null,null);
if (cursor.moveToFirst()){
rowLat = cursor.getString(cursor.getColumnIndex("latitude"));
}
cursor.close();
db.close();
// return coordinates
return rowLat;
}
Change onListItemClick to this:
public void onListItemClick(ListView l, View v, int position, long id) {
DatabaseHelper helper = new DatabaseHelper(this);
// ??? selectedFromList = (String) (l.getItemAtPosition(position));
// ??? selectedItem = l.getItemIdAtPosition(position);
String rowLat = helper.getLatitudeFromId(id);
Toast.makeText(getApplicationContext(), rowLat, Toast.LENGTH_SHORT).show();
}
Note: l.getItemAtPosition(position) returns a view not string neither int
i actually worked my way out. Strangely though, i changed my query to this
Cursor cursor = db.query(TABLE_COORDINATES, new String[] {KEY_DATE}, null, null, null, null,null);
just letting the selection to null and only having the column that i wanted, and it worked! This question can be marked as answered.
I am attempting to delete a record from my database,
Short Summary:
My database populates a listview
The user can click the listview and
view more details on a new activity
I want to able to delete the
record from this new activity
CODE
I have a class named ModuleDatabaseHandler that manages the database. In this, I have a method called getData() that populates records to a ListView in ActivityViewAll:
ModuleDatabaseHandler
public ArrayList<String> getData() {
// TODO Auto-generated method stub
String[] columns = new String[] { KEY_ROWID, KEY_MODULE_CODE,
KEY_MODULE_NAME, KEY_LECTURE_PRACTICAL,
KEY_LECTURE_PRACTICAL_SHORT, KEY_LECTURE_DAY,
KEY_LECTURE_DAY_SHORT, KEY_START_TIME, KEY_END_TIME,
KEY_LOCATION, ADDITIONAL_INFO };
Cursor c = ourDatabase.query(DATABASE_MODULES, columns, null, null,
null, null, null);
ArrayList<String> results = new ArrayList<String>();
int indexModCode = c.getColumnIndex(KEY_MODULE_CODE);
int indexLectPracShort = c.getColumnIndex(KEY_LECTURE_PRACTICAL_SHORT);
int indexLectDayShort = c.getColumnIndex(KEY_LECTURE_DAY_SHORT);
int indexLectStart = c.getColumnIndex(KEY_START_TIME);
int indexLectLoc = c.getColumnIndex(KEY_LOCATION);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
results.add(c.getString(indexModCode) + " "
+ c.getString(indexLectPracShort) + " "
+ c.getString(indexLectDayShort) + " "
+ c.getString(indexLectStart) + " "
+ c.getString(indexLectLoc));
}
return results;
}
This data is read in by ActivityViewAll:
ActivityViewAll
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_modules_test);
ModuleDatabaseHandler info = new ModuleDatabaseHandler(this);
info.open();
ArrayList<String> data = info.getData();
info.close();
l = (ListView) findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, data);
l.setAdapter(adapter);
l.setOnItemClickListener(this);
}
I have another method in the ModuleDatabaseHandler class called getAllData() that allows the user to press a ListView item and read full details about the item on a new activity, ActivityFullDetails:
public String getAllData(int specified_position) {
// TODO Auto-generated method stub
int position = specified_position;
if(c.moveToPosition(specified_position)) {
String result = "";
for(int columnIndex = 0; columnIndex<c.getColumnCount();columnIndex++) {
result += c.getString(columnIndex)+" ";
}
return result;
} else {
throw new IllegalArgumentException("Row " + specified_position + " does not exist");
}
}
The data is transfered from the listView in ActivityViewAll to ActivityFullDetails using onItemClick:
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
TextView temp = (TextView) view;
Toast.makeText(this, temp.getText() + " " + i, Toast.LENGTH_SHORT)
.show();
ModuleDatabaseHandler info = new ModuleDatabaseHandler(this);
info.open();
String module_info = info.getAllData(i);
info.close();
Intent fullModuleDetails = new Intent();
fullModuleDetails.setClassName("com.example.collegetimetable",
"com.example.collegetimetable.ModuleDetails");
fullModuleDetails.putExtra("list1", module_info);
startActivity(fullModuleDetails);
}
Back in the ModuleDatabaseHandler class, I created a method called deleteEntry to attempt to delete a row:
public void deleteEntry(long row){
ourDatabase.delete(DATABASE_MODULES, KEY_ROWID + "=" + row, null);
}
The Problem
How can I pass the ROW_ID from the ModuleDatabaseHandler class to the listView in ActivityViewAll and then to the ActivityFullDetails so I can delete the record?
SOLVED
Thanks to Serge who helped me solve this, by creating a getRowId method as seen in the accepted answer. Although I did have to add a cursor query within the method which is not shown in the accepted answer i.e.:
public int getRowID(int specified_position) {
String[] columns = new String[]{ KEY_ROWID, KEY_MODULE_CODE, KEY_MODULE_NAME, KEY_LECTURE_PRACTICAL, KEY_LECTURE_DAY, KEY_START_TIME,KEY_END_TIME, KEY_LOCATION, ADDITIONAL_INFO};
Cursor c = ourDatabase.query(DATABASE_MODULES, columns, null, null, null, null, null);
// rest of method as shown below
}
This method is called in the ActivityViewAll activity page from an instance of ModuleDatabaseHandler class, passed to the ActivityFullDetails page using putExtra,(and received using getIntent().getExtras as usual)..the delete method can then use the rowid.
Add function
public int getRowID(int specified_position) {
int position = specified_position;
if(c.moveToPosition(specified_position)) {
return c.getInteger(c.getColumnIndex(KEY_ROWID));
} else {
throw new IllegalArgumentException("Row " + specified_position + " does not exist");
}
}
And then to get it use
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
TextView temp = (TextView) view;
Toast.makeText(this, temp.getText() + " " + i, Toast.LENGTH_SHORT)
.show();
ModuleDatabaseHandler info = new ModuleDatabaseHandler(this);
info.open();
String module_info = info.getAllData(i);
int rowID = info.getRowID(i);
info.close();
Intent fullModuleDetails = new Intent();
fullModuleDetails.setClassName("com.example.collegetimetable",
"com.example.collegetimetable.ModuleDetails");
fullModuleDetails.putExtra("list1", module_info);
fullModuleDetails.putExtra("rowid", rowID);
startActivity(fullModuleDetails);
}