I am building a custom ListView (card style) and would like to have an edit and delete button on the card. In order to invoke the methods on the correct database rows, I need to know which _id (View) the user selected.
Currently, I am using a context menu which is pretty easy
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
position = (int) info.id;
MenuInflater m = getMenuInflater();
m.inflate(R.menu.history_popup_menu, menu);
}
#Override
public boolean onContextItemSelected(final MenuItem item) {
switch(item.getItemId()){
case R.id.delete:
...
in this case, I get the id (position) in the onCreateContextMenu
I am wanting to get rid of the context menu now and just have edit and delete on the card itself.
How do I go about retrieving the _id from the database and assign it to a value to be used in my delete/edit method?
This is my method for creating the list
private void addItemsToList(){
Cursor cursor = db.getAllLogs();
Log.d("history.java", "finished Cursor cursor = db.getAllLogs();");
String[] from = {"_id", "date", "gallons", "pricePerGallon", "odometer", "filledOrNot", "comments", "totalSpent"};
int[] to = {deleteVal, R.id.cardDate, R.id.cardGallons, R.id.cardPrice, R.id.cardOdometer, R.id.cardFilledOrNot, R.id.cardComments, R.id.usd};
adapter = new SimpleCursorAdapter(this, R.layout.history_list_item, cursor, from, to, 0);
String filledOrNotVal = String.valueOf(R.id.cardFilledOrNot);
if (filledOrNotVal == "False"){
Log.d("history", "False");
} else {
Log.d("history", "True");
}
listContent.setAdapter(adapter);
}
Related
What i want is when the user clic on contact a context Menu appear with item "delete" so i did this, but the problem is I want that when he clic on delete a row from Sqlit ( that corresponds to the contact I just clicked)
Activity.class
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int i = info.position;
switch (item.getItemId()) {
case R.id.delete:
dbHandler.deleteEtudiant(i);
Toast.makeText(this,"deleted "+i, Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
MyDBHandler.class
public void deleteEtudiant(int i)
{
SQLiteDatabase db = this.getWritableDatabase();
db.delete("etudiant", "Id+ =" + i, null);
}
The problem with your code is that your are getting the id of "AdapterContextMenuInfo" object and sending it to the database "delete()" method. But actually you need to send the id of the of the item of database, the value that is stored in "ID" column of that particular row in SQlite Database.
Please have a look on the tutorial given below, specially check the "getContact()" and "deleteContact()" method of the tutorial.
http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
I have a problem. I try to delete the record from the database. I have no idea, but how to do it. I tried something like this, but not quite work.
The basic gist is that I trying to delete from the database based on list item position, not database row ID. How delete base database row ID?
ListView listawszystkich;
public int pozycja;
DatabaseDEO db = new DatabaseDEO(this);
final String[] skad = new String[]{Database.tables.Transakcje.Kolumny.kwota, Database.tables.Transakcje.Kolumny.data, Kategorie.KOLUMNY.nazwa_kategorii, Database.tables.Transakcje.Kolumny.komentarz};
final int[] dokad = new int[]{R.id.kwotaglowna,R.id.dataglowna,R.id.kategoriaglowna,R.id.komentarzglowny};
private SimpleCursorAdapter adapterspinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transakcje2);
listawszystkich = (ListView) findViewById(R.id.listawszystkich);
listawszystkich.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
pozycja = position+1;
}
});
Cursor kursorwszystkie = db.wszystkietransakcje();
adapterspinner = new SimpleCursorAdapter(getApplicationContext(), R.layout.activity_transakcje,kursorwszystkie,skad, dokad,0);
adapterspinner.notifyDataSetChanged();
listawszystkich.setAdapter(adapterspinner);
registerForContextMenu(listawszystkich);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId()==R.id.listawszystkich) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_list,menu);
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.delete:
db.usuwanietransakcji(pozycja);
Transakcje.this.recreate();
Toast.makeText(getApplicationContext(), "Delete", Toast.LENGTH_SHORT).show();
default:
return super.onContextItemSelected(item);
}
Method to delete row (in DatabaseDEO):
public void usuwanietransakcji(int id_transakcji){
SQLiteDatabase db = DbHelper.getWritableDatabase();
db.execSQL("DELETE FROM " + Transakcje.NAZWA_TABELI+ " WHERE "+Transakcje.Kolumny.id_transakcji+"='"+id_transakcji+"'");
db.close();
}
Looks like you're trying to delete from the database based on list position rather than row ID:
db.usuwanietransakcji(pozycja);
I'm guessing id_transakcji is a unique value similar to a row ID? First you'll need to declare Cursor kursorwszystkie as a member variable outside of the onCreate method, but still populate it on the same line.
In onContextItemSelected() you'll need to query your cursor again:
case R.id.delete: {
// Move to the selected row
kursorwszystkie.moveToPosition(info.position);
// Get the column ID of id_transakcji
final int col_id = kursorwszystkie.getColumnIndex(Database.tables.Transakcje.Kolumny.id_transakcji);
// Get id_transakcji
final int id_transakcji = kursorwszystkie.getInt(col_id);
// Query the database
db.usuwanietransakcji(id_transakcji);
Transakcje.this.recreate();
Toast.makeText(getApplicationContext(), "Delete", Toast.LENGTH_SHORT).show();
break;
}
Note the addition of {} as I'm declaring a variable inside a switch case. Also add a break; at the end of the case so the code doesn't fall through into the default block. Let me know if that works.
I have an expandListView diaryDisplaylist
this is adapter DiaryExpandListAdapter mAdapterForAll which will be used to fill the diaryDisplayList
code snippet which does this:
mAdapterForAll = new DiaryExpandListAdapter(this, diaryList);
diaryDisplaylist.setAdapter(mAdapterForAll);
diarylist is of type:
diaryList = new ArrayList<Object>();
diaryList will have all items from about 8 databases from which expandlist is grouped according to date of the time of entry present in the database.
It displays it perfectly.
Now i have expandlist full of elements belonging to different databases.
So for edit and delete functionality i have used
diaryDisplaylist.setOnCreateContextMenuListener(this);
code snippet for contextMenu:
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
int type = ExpandableListView.getPackedPositionType(info.packedPosition);
if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
menu.add(0, Constants.MENU_EDIT, 0, "Edit");
menu.add(0, Constants.MENU_DELETE, 1, "Delete");
}
}
#Override
public boolean onContextItemSelected(android.view.MenuItem item) {
ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case Constants.MENU_EDIT:
// once i get item belonging to respective database i can edit
return true;
case Constants.MENU_DELETE:
return true;
default:
return super.onContextItemSelected(item);
}
}
In on contextMenuItem selected how can i find which database that item belongs to?
I cannot use adapter to find me the object because i dont have groupPosition and childPosition in contextItemSelected.
If i could get those i could have simply used.
Object selectedObject = mAdapterForAll.getChild(groupPosition, childPosition);
then using selectedObject i could have found out
if(selectedObject isInstanceOf db1)
to get group and child position i used
Object obj = diaryList.get((int) info.packedPosition);
in onContextItemSelected it worked.
Sorry the above code was buggy this code works fine for me to determine the group and child position from expandlist view
int groupPos = 0, childPos = 0;
int type = ExpandableListView.getPackedPositionType(info.packedPosition);
if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
groupPos = ExpandableListView
.getPackedPositionGroup(info.packedPosition);
childPos = ExpandableListView
.getPackedPositionChild(info.packedPosition);
}
I'm doing a proyect where i have a view with multiple listview created at runtime, every listview load specifics rows of a database. and i want to implement a contextmenu. The problem is how can i get the row of the listview to retieve the id of the database? How can i get my list adapter inside the contextmenu ? or some other solution. Thanks!
here is a part of the code...
private void makeView(){
yearsArray = db.getUniqueYears(TABLE_NAME);
for (int i = 0; i < yearsArray.size() ; i++){
list = db.getDocByYear(TABLE_NAME, yearsArray.get(i));
custom_adapter = new Document_adapter(this, list);
ListView lv = new ListView(this);
lv.setAdapter(custom_adapter);
lv.setBackgroundResource(R.drawable.title_container_bg);
registerForContextMenu(lv);
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.doc_options, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
/*
*/
return super.onContextItemSelected(item);
}
If you set your database up properly you can just do this info.id; in your onContextItemSelected and that gives the database id
How can I set title of the context menu from the selected Listview item? This below is my main activity.
public class OListActivity extends ListActivity {
......
......
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
registerForContextMenu(getListView());
......
......
MatrixCursor cursor;
cursor = NameManager.getnameList();
startManagingCursor(cursor);
String[] from = { "name", "info", "status", BaseColumns._ID };
int[] to = { R.id.name, R.id.info, R.id.status };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, from, to);
setListAdapter(adapter);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Menu");// TODO Change to name of selected listview item.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
.....
.....
I need to set menu.setHeaderTitle to R.id.name. I'm aware of another similer question but it don't mention about dealing with a complex ListView with multiple textviews.
Use the ContextMenuInfo parameter from the onCreateContextMenu() method:
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo info;
try {
// Casts the incoming data object into the type for AdapterView objects.
info = (AdapterView.AdapterContextMenuInfo) menuInfo;
} catch (ClassCastException e) {
// If the menu object can't be cast, logs an error.
Log.e(TAG, "bad menuInfo", e);
return;
}
Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
if (cursor == null) {
// For some reason the requested item isn't available, do nothing
return;
}
// if your column name is "name"
menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex("name")));
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
I know this is quite an old post and is the correct answer as well. However, while using this today I came across something I will like to add.
The ContextMenuInfo parameter is used to find the exact item position which initiated the ContextMenu i.e our adpater item.
Hence, it can return an item of type defined in the Adapter's getItem() method using that position info.position, as in the above the getItem() method returns a Cursor object.
(In my case it returned a Model class and then I realized that to set the Title via menu.setHeaderTitle() I can pass my methods that my model supports like model.getItamName())
Also, remember if your AdapterView contains any header you will have to exclude them while fetching the position using menuInfo. Like,
Cursor cursor = (Cursor) getListAdapter().getItem(info.position - yourList.getHeaderViewsCount());
Hope this helps someone. :)