Currently, in anotherclass, I need to delete 1 item when I upload success a file call deleteCallWhenUploadSuccess.
In this class, I using fileName to determined item need to delete.
But it doesn't delete item in ListView from Layout activity_call_history.xml
In DAO class I delete with code:
public void deleteCallWhenUploadSuccess(String fileNameWhis)
{
db = callDatabaseHelper.getWritableDatabase();
String where = CallDatabaseHelper.FILE_NAME + "='" + fileNameWhis + "'";
db.delete(CallDatabaseHelper.TABLE_NAME, where, null);
}
And in other class I using it:
DAO.deleteCallWhenUploadSuccess(filename);
I write code to remove an item on ListView in event onActionItemClicked.
On the DAO class I start to delete an item with rowId:
public void deleteCallV2(int rowId) {
db = callDatabaseHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from "+CallDatabaseHelper.TABLE_NAME+" where rowId = "+String.valueOf(rowId),null);
while(cursor.moveToNext()){
this.rowId = CallDatabaseHelper.ROW_ID +"="+cursor.getString(cursor.getColumnIndex(CallDatabaseHelper.ROW_ID));
}
db.delete(CallDatabaseHelper.TABLE_NAME, this.rowId, null);
}
Code I used to delete item in ListView of Layout historyAdapter write code in HistoryFragment.java, I was comment in code to easy read:
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.deleteAction:
// Calls getSelectedIds method from ListViewAdapter Class
selected = historyAdapter
.getSelectedIds();
// Captures all selected ids with a loop
for (int i = (selected.size() - 1); i >= 0; i--) {
if (selected.valueAt(i)) {
Call selecteditem = historyAdapter
.getItem(selected.keyAt(i));
// Remove selected items following the ids
historyAdapter.remove(selecteditem);
}
}
getFragmentManager().beginTransaction().replace(R.id.container,new HistoryFragment()).commit();
// Close CAB
mode.finish();
return true;
case R.id.allAction:
historyAdapter.toggleAll(listView);
Toast.makeText(getActivity(), "Đã chọn tất cả", Toast.LENGTH_SHORT).show();
return true;
default:
return false;
}
}
But it only work when I select item with long press and select item or select all to delete. It using ID to delete item.
Since I didn't got much but according to the heading of the question which says to remove an item in list I can suggest you to use notifyDataSetChanged() whenever you are removing a view so that your listview could update itself whenever its changed
A little code which demonstrate this task is
adapter = new MyListAdapter(this);
lv = (ListView) findViewById(android.R.id.list);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
AlertDialog.Builder adb=new AlertDialog.Builder(MyActivity.this);
adb.setTitle("Delete?");
adb.setMessage("Are you sure you want to delete " + position);
final int positionToRemove = position;
adb.setNegativeButton("Cancel", null);
adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MyDataObject.remove(positionToRemove);
adapter.notifyDataSetChanged();
}});
adb.show();
}
});
Related
The code for the spinner is below, The spinners on my app tend to duplicate it's content sometimes for some weird reason. How do I prevent this from happening?:
Spinner spinnerG = (Spinner) findViewById(R.id.spGroup);
final ArrayAdapter<String> dataAdapterG = new ArrayAdapter<>
(this, R.layout.simple_spinner_item, groups);
dataAdapterG.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
spinnerG.setAdapter(dataAdapterG); //general basics //sets up the group spinner, filled with the groups list
spinnerG.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
selectedGroup = groups.get(position);
studentsToShow.clear();
for(int i = 0; i < studList.size(); i++){
if(studList.get(i).getGroup().equals(selectedGroup)){
Students a = new Students();
a.setFirstName(studList.get(i).getFirstName());
a.setLastName(studList.get(i).getLastName());
a.setStudentID(studList.get(i).getStudentID());
a.setGroup(studList.get(i).getGroup());
studentsToShow.add(a); //when a new group is chosen the list of students in the selected group needs to be updated
} //this re uses the code earlier to make a list of student in the selected group
}
updateSpS(); //updates the student spinner
}
public void onNothingSelected(AdapterView<?> parent){
}
});
The spinner will duplicate if you have put this oncreate event. Put the spinner population code on the onResume method.
From the snippet shared with the question, its hard to guess why OP would have duplicate value. An educated guess is his onItemSelected() is being called multiple times.
Spinner's (in my personal view, is one of the worst android widget) onItemSelected() can be called multiple times for different reasons, one of the thing I would recommend to try this way -
class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener {
boolean userSelect = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
userSelect = true;
return false;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (userSelect) {
// Your selection handling code here
userSelect = false;
if(view!=null){
selectedGroup = groups.get(position);
studentsToShow.clear();
for(int i = 0; i < studList.size(); i++){
if(studList.get(i).getGroup().equals(selectedGroup)){
Students a = new Students();
a.setFirstName(studList.get(i).getFirstName());
a.setLastName(studList.get(i).getLastName());
a.setStudentID(studList.get(i).getStudentID());
a.setGroup(studList.get(i).getGroup());
studentsToShow.add(a); //when a new group is chosen the list of students in the selected group needs to be updated
} //this re uses the code earlier to make a list of student in the selected group
}
updateSpS(); //updates the student spinner
}
}
}
}
And then set -
SpinnerInteractionListener listener = new SpinnerInteractionListener();
spinnerG.setOnTouchListener(listener);
spinnerG.setOnItemSelectedListener(listener);
This at the same time takes care unwanted callbacks of onItemSelected() without user touch and if any previous leaked listeners.
I have a ListView with rows with different layouts. So I'm using the pattern of ViewHolder.
If the user clicks on a row, one sub-layout of the same row must be shown/hidden.
viewHolder.btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = (int) v.getTag();
Log.d(TAG, "Line in position " + position + " clicked");
if (!checkBoxSendChoice[position]) {
checkBoxSendChoice[position] = true;
viewHolder.layout_choice.setVisibility(View.VISIBLE);
} else {
checkBoxSendChoice[position] = false;
viewHolder.layout_choice.setVisibility(View.GONE);
}
}
});
However I noticed that the entire ListView is refreshed (getView is called multiple times for all rows), because of setVisibility(). If I comment out the two setVisibility() instructions, the ListView isn't refreshed anymore.
Is it possible to optimize and avoid refreshing all the views in the ListView?
I think there is a better way of doing this. Instead of editing the view directly, you should have a Boolean isVisible inside the list item and change that, then notify the adapter that an item has changed. This will make the holder re-bind to the item. And inside the holder's bind function you can set the view's visibility depends on the boolean. Here is a rough example (half pseudo code):
List<MyItem> items;
viewHolder.btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = (int) v.getTag();
Log.d(TAG, "Line in position " + position + " clicked");
checkBoxSendChoice[position] != checkBoxSendChoice[position];
items.get(position).isVisible = heckBoxSendChoice[position];
adapter.notifyItemRangeChanged(position, 1);
}
});
class MyItem {
boolean isVisible = true;
}
class holder {
View layout_choice;
private void onBind(MyItem item) {
if (item.isVisible) {
layout_choice.setVisibility(View.VISIBLE);
} else {
layout_choice.setVisibility(View. GONE);
}
}
}
By notifying the adapter with notifyItemRangeChanged, the adapter will know what items have been update and therefore will only refresh them.
If you want i'll be happy to edit my answer with a working tested example. Hope this helps!
I can't find an answer to delete in a listview created using SimpleCursorAdapter
So i make this listview in a fragment, here's the code
final Cursor cursor = myDb.cautarevenituri();
// The desired columns to be bound
final String[] columns = new String[] {
DatabaseHelper.COL_2,
DatabaseHelper.COL_3
};
int[] toviewids = new int[] { R.id.nume_item,R.id.valoare_item};
dataAdapter = new SimpleCursorAdapter(getActivity().getBaseContext(),R.layout.item_layout,cursor,columns,toviewids,0);
//
final ListView listView = (ListView)getView().findViewById(R.id.listView_venituri);
listView.setAdapter(dataAdapter);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long arg3) {
Toast.makeText(getActivity(), " " + position, Toast.LENGTH_LONG).show();
//delete from listview in database and listview too??
//
//
return false;
}
});
Thank you.
Delete from Database and refresh the listview.
You have to update your list that you passed into the adapter and then call adapter.notifyDataSetChanged()
Use the swapCursor() method to update the data inside a SimpleCursorAdapter:
myDb.getWriteableDatabase().delete(TABLE_NAME, KEY_ID + "=?", position);
Cursor newCursor = myDb.getReadableDatabase().query(**etc.**);
dataAdapter.swapCursor(newCursor);
I need to delete an item permanently from ListView and then from database. I have a DatabaseHandler.java class, which has the delete function as:
// Deleting single contact, in DatabaseHandler.java class
public void deleteContact(Contact contact) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
new String[] { String.valueOf(contact.getID()) });
db.close();
}
Then I have a FriendList.java class, when the user's friends are displayed as an item in ListView. When I long press on an item, then I get the option of "Delete" and "Cancel" in Dialog Box. Now, when I click on delete, the item is deleted from the ListView, but, not from the database. How can I delete it from database as well?
The code for getting the option of "Delete" and "Cancel"
listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long id) {
// TODO Auto-generated method stub
Intent i = new Intent(FriendList.this, Delete_Confirm.class).addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
//I am sending position of listitem in putExtra below//
i.putExtra("position", position);
startActivityForResult(i,CONFIRM);
item2 = (String) arg0.getItemAtPosition(position);
//Toast.makeText(FriendList.this, "Clicked"+item2, Toast.LENGTH_SHORT).show();
int l = item2.length();
c=0;
for(int j=0; j<=l; j++){
if(item2.charAt(j) != '9' || item2.charAt(j+1) != '1'){
c++;
}
else {
//Do nothing
break;
}
num = item2.substring(c, l);
}
Toast.makeText(FriendList.this, "Clicked: "+num, Toast.LENGTH_SHORT).show();
return true;
}
});
The corresponding code for onActivityResult is as follows:
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (CONFIRM) :
if(resultCode==RESULT_OK){
int posi = data.getIntExtra("position",0);
Log.d("msg","position is " + posi);
Log.d("msg","Do we reach here?");
final StableArrayAdapter adapter = new StableArrayAdapter(this,
android.R.layout.simple_list_item_1, list);
//db.deleteContact(posi);
list.remove(posi);
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
break;
}}
Please suggest how can I delete it from database as well. Any help would be highly appreciated.
EDIT:
On uncommenting db.deleteContact(posi), I get the following error:
The method deleteContact(Contact) in the type DatabaseHandler is not applicable for the arguments (int)
Note that the function deleteContact has contact variable of the type Contact.
Its a compilation error.
You need to pass a Contact object to the method, not an integer.
When you delete.... Try Deleting first from database then from ListView..
example:
db.deleteContact(list.get(posi)); // this will get string
list.remove(posi);
DatabaseHandler class.......
public void deleteContact(String name){
Log.d("Name:",""+ name);
db.delete(TABLE_CONTACTS, KEY_NAME + " = ?", new String[] { name });
}
You can delete from database first then from ListView. And suggest Iterator to remove list element.
I think the problem is that position is not the corresponding id in the database. A possible solution would be to add a tag with the database id of the contact you have in this listitem. And when you remove it you get the tag with the id and delete the item from the database.
Edit (added clarification):
I would add in your listviewadapter something like:
yourcontactview.setTag(contact.getId());
in which you add to your view a tag with the database id of the corresponding contact.
Then where you delete the contact I would get the contact you want to delete with something like this:
Contact deletecontact = db.getContact(view.getTag());
db.deleteContact(deletecontact);
Of course you could change your
deleteContact(Contact contact) to a method in which you give the id instead of the contactobject.
This should hopefully work.
can anybody tell me how to change the visibility of a menuitem from another activity?
I have two activities "activity A and B". in one activity A when I press a menu item it saves some strings to the list of activity B and In activity A menuitem visibility set to false. now I want that when I delete that item from activity B which I saved from activity A, with this delete the menuitem visibility in activity A changes to true and it become visible again? so how can I do this. I using database to populate listview.
Activity A
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.atherosclerosis, menu);
return true;
}
// for starting activity from the option or menu//
#Override
public boolean onOptionsItemSelected(MenuItem item) {
SharedPreferences myPrefs = PreferenceManager.getDefaultSharedPreferences(this);
final SharedPreferences.Editor editor = myPrefs.edit();
favClicked = myPrefs.getBoolean("menu_item", false);
switch (item.getItemId()) {
case R.id.id_favorit:
// Add it to the DB and re-draw the ListView
myDb.insertRow("Atherosclerosis", 0, "");
Toast.makeText(getApplicationContext(), "Item Added to favorite list!", Toast.LENGTH_SHORT).show();
favClicked=true;
editor.putBoolean("menu_item", favClicked);
editor.commit();
invalidateOptionsMenu();
return true;
case R.id.id_favorit2:
myDb.deleteRow("Atherosclerosis");
Toast.makeText(getApplicationContext(), "Item deleted from favorite list!", Toast.LENGTH_SHORT).show();
favClicked=false;
editor.putBoolean("menu_item", favClicked);
editor.commit();
invalidateOptionsMenu();
return super.onOptionsItemSelected(item);
}
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(favClicked==true){
menu.findItem(R.id.id_favorit).setVisible(false);
menu.findItem(R.id.id_favorit2).setVisible(true);
}else{
menu.findItem(R.id.id_favorit).setVisible(true);
menu.findItem(R.id.id_favorit2).setVisible(false);
}
Activity B
private void populateListViewFromDB() {
Cursor cursor = myDb.getAllRows();
// Allow activity to manage lifetime of the cursor.
// DEPRECATED! Runs on the UI thread, OK for small/short queries.
startManagingCursor(cursor);
// Setup mapping from cursor to view fields:
String[] fromFieldNames = new String[]
{DBAdapter.KEY_NAME, DBAdapter.KEY_STUDENTNUM};
int[] toViewIDs = new int[]
{R.id.item_name};
// Create adapter to may columns of the DB onto elemesnt in the UI.
SimpleCursorAdapter myCursorAdapter =
new SimpleCursorAdapter(
this, // Context
R.layout.item_layout, // Row layout template
cursor, // cursor (set of DB records to map)
fromFieldNames, // DB Column names
toViewIDs // View IDs to put information in
);
// Set the adapter for the list view
ListView myList = (ListView) findViewById(R.id.favlistView1);
myList.setAdapter(myCursorAdapter);
}
private void registerListClickCallback() {
ListView myList = (ListView) findViewById(R.id.favlistView1);
//This code is for to delete the single item from the listview of favorite list
myList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, final long arg3) {
Cursor cursor = myDb.getRow(arg3);
if (cursor.moveToFirst()) {
new AlertDialog.Builder(FavoriteDiseases.this)
.setTitle("Delete Item")
.setMessage("Do you want to delete this disease?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
myDb.deleteItem(arg3);
populateListViewFromDB();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.show();
}
return true;
}
});
Need a little more context for a good answer how are the activities related is one calling the other?
But in general if activity a is calling activity b. Then you could just call startActivityForResult when starting activity b. When b is finished return a status that informs activity a that the item has been deleted.
To update the menu assuming you are creating your menu by overriding onCreateOptionsMenu, then just have that method check a flag to set a state of the menu item. Then in your onActivityResult method set the flag based on the result of activity b and call invalidateOptionsMenu() which will redraw your options menu.