I've got a Listview showing files currently on the SDcard. When you long press the file, a context menu pops up.
My question is: how do I pass in the selected item to the Context Menu in order to delete the file from the list, and is it possible to also delete it from the SDcard using this? My Code is as follows:
public class PlayListActivity extends ListActivity {
// Songs list
public ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playlist);
ArrayList<HashMap<String, String>> songsListData = new ArrayList<HashMap<String, String>>();
SongsManager plm = new SongsManager();
// get all songs from sdcard
this.songsList = plm.getPlayList();
// looping through playlist
for (int i = 0; i < songsList.size(); i++) {
// creating new HashMap
HashMap<String, String> song = songsList.get(i);
// adding HashList to ArrayList
songsListData.add(song);
}
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(this, songsListData,
R.layout.playlist_item, new String[] { "songTitle", "songDate" }, new int[] {
R.id.songTitle, R.id.songDate });
setListAdapter(adapter);
// setup ListView item
ListView lv = getListView();
registerForContextMenu(lv);
notifyDataSetChanged();
// listening to single listitem click
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting listitem index
int songIndex = position;
// Starting new intent
Intent in = new Intent(getApplicationContext(),
Bandboxstage.class);
// Sending songIndex to PlayerActivity
in.putExtra("songIndex", songIndex);
setResult(100, in);
// Closing PlayListView
finish();
}
});
}
private void notifyDataSetChanged() {
// TODO Auto-generated method stub
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.delete:
Toast.makeText(this, "Delete Called.", Toast.LENGTH_SHORT).show();
deleteFile(info.id);
return true;
case R.id.share:
Toast.makeText(this, "Share Called.", Toast.LENGTH_SHORT).show();
default:
return super.onContextItemSelected(item);
}
}
private void deleteFile(long id) {
// TODO Auto-generated method stub
}
}
Well your answer is in your implementation itself. If you notice, in your onContextItemSelected()
, the following statement brings in the info of the item you have selected in your main listview.
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
You can use info.position to find out the position of your item in the list and then get the object from your ArrayList using songsList.get(info.position).
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.delete:
Toast.makeText(this, "Delete Called.", Toast.LENGTH_SHORT).show();
//Make sure songsList is a global variable so that it can be accessed here.
HashMap<String, String> song = songsList.get(info.position);
//Call your delete function to delete the song.
return true;
case R.id.share:
Toast.makeText(this, "Share Called.", Toast.LENGTH_SHORT).show();
default:
return super.onContextItemSelected(item);
}
}
Refer this LINK it passes varialble on long click.
below is the deletefile function
file.delete() will delete the file.
Related
Below is my activity class which retrieve data from sqllite db and generate the custom listview with 3textviews and 1 toggle button
Activity class:
public class PaymentReminderActivity extends ActionBarActivity {
ReminderDataSource datasource;
// Array of booleans to store toggle button status
public boolean[] status = {
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment_reminder);
datasource = new ReminderDataSource(this);
/** Restore from the previous state if exists */
if(savedInstanceState!=null){
status = savedInstanceState.getBooleanArray("status");
}
//GET ALL DATA
datasource.open();
final List<ReminderClass> values = datasource.getAllUsers();
datasource.close();
ListView lvReminder = (ListView) findViewById(R.id.lv_countries);
registerForContextMenu(lvReminder);
OnItemClickListener itemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> lv, View item, int position, long id) {
ListView lView = (ListView) lv;
SimpleAdapter adapter = (SimpleAdapter) lView.getAdapter();
HashMap<String,Object> hm = (HashMap) adapter.getItem(position);
/** The clicked Item in the ListView */
RelativeLayout rLayout = (RelativeLayout) item;
/** Getting the toggle button corresponding to the clicked item */
ToggleButton tgl = (ToggleButton) rLayout.getChildAt(2);
String strStatus = "";
if(tgl.isChecked()){
tgl.setChecked(false);
strStatus = "Off";
status[position]=false;
}else{
tgl.setChecked(true);
strStatus = "On";
status[position]=true;
}
Toast.makeText(getBaseContext(), (String) hm.get("txt") + " : " + strStatus, Toast.LENGTH_SHORT).show();
}
};
lvReminder.setOnItemClickListener(itemClickListener);
// Each row in the list stores country name and its status
List<HashMap<String,Object>> aList = new ArrayList<HashMap<String,Object>>();
for (int i = 0; i<values.size(); i++) {
HashMap<String, Object> hm = new HashMap<String, Object>();
hm.put("txt", values.get(i).getType());
hm.put("txt2", values.get(i).getDesc());
hm.put("txt3", values.get(i).getDay() + " of every month");
hm.put("stat", status[i]);
aList.add(hm);
}
// Keys used in Hashmap
String[] from = {"txt","txt2","txt3","stat" };
// Ids of views in listview_layout
int[] to = { R.id.tv_item,R.id.tv_item2, R.id.tv_item3, R.id.tgl_status};
// Instantiating an adapter to store each items
// R.layout.listview_layout defines the layout of each item
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.lv_layout, from, to);
lvReminder.setAdapter(adapter);
}
/** Saving the current state of the activity
* for configuration changes [ Portrait <=> Landscape ]
*/
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBooleanArray("status", status);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_payment_reminder, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_add) {
Intent intent = new Intent();
intent.setClass(this, NewReminderActivity.class);
startActivityForResult(intent, 0);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId()==R.id.lv_countries) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_list, menu);
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
long selectid = info.id; //_id from database in this case
int selectpos = info.position;
switch(item.getItemId()) {
case R.id.add:
// add stuff here
return true;
case R.id.edit:
// edit stuff here
return true;
case R.id.delete:
return true;
default:
return super.onContextItemSelected(item);
}
}
}
Toggling toggle button on list view have no problem.
Once i leave that activity and came back the state is resetted.
In my List2 activity (extending ListActivity), I am deleting a file and after that I call the method init(); to refresh my ListView but it's not refreshing, it's only duplicating (appearing old and new ones) items.
And if I click on one of those new generated items it will force close. I know notifyDatasetChanged doesn't work in my case.
Any help would be appreciated.
This is my List2 Class :
public class List2 extends ListActivity {
ListView lv;
private ListAdapter adapter;
public ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
public ArrayList<HashMap<String, String>> myHash = new ArrayList<HashMap<String, String>>();
// private ArrayList<DataSetObserver> observers = new
// ArrayList<DataSetObserver>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list2);
init();
lv = getListView();
registerForContextMenu(getListView());
// listening to single listitem click
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
// // Starting new intent
Intent in = new Intent(getApplicationContext(),
secondActivity.class);
// Sending songIndex to PlayerActivity
in.putExtra("Index", fileIndex);
// setResult(100, in);
// Closing PlayListView
startActivity(in);
finish();
}
});
}
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
}
public boolean onContextItemSelected(MenuItem item) {
final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
switch (item.getItemId()) {
case R.id.delete:
File file = new File(Path);
if (file.exists()) {
file.delete();
init();
}
return true;
default:
return super.onContextItemSelected(item);
}
}
public ArrayList<HashMap<String, String>> getPlayList() {
File home = new File(MEDIA_PATH);
if (home.listFiles(new FileExtensionFilter()).length > 0) {
for (File file : home.listFiles(new FileExtensionFilter())) {
HashMap<String, String> song = new HashMap<String, String>();
song.put(
"songTitle",
file.getName().substring(0,
(file.getName().length() - 4)));
song.put("songPath", file.getPath());
songsList.add(song);
}
}
// return songs list array
return songsList;
}
void init() {
this.getPlayList();
// looping through playlist
for (int i = 0; i < songsList.size(); i++) {
// creating new HashMap
HashMap<String, String> song = songsList.get(i);
myHash.add(song);
}
adapter = new SimpleAdapter(this, myHash, R.layout.playlist_item,
new String[] { "songTitle", "singerName" }, new int[] {
R.id.songTitle, R.id.singerName });
setListAdapter(adapter);
}
}
Its because you are adding myHash without clearing it, so it contains all of the old entries as well as the new ones. Simply call clear before you add more items to it.
void init() {
this.getPlayList();
myHash.clear();
// looping through playlist
for (int i = 0; i < songsList.size(); i++) {
// creating new HashMap
HashMap<String, String> song = songsList.get(i);
myHash.add(song);
}
adapter = new SimpleAdapter(this, myHash,
R.layout.playlist_item, new String[] { "songTitle","singerName" }, new int[] {
R.id.songTitle,R.id.singerName });
setListAdapter(adapter);
}
I have code like this :
public class ListConActivity extends Activity {
private String[] Distro = { "Ubuntu", "Arch Linux", "Mandriva",
"Open Suse", "IGOS Nusantara", "Linux Mint", "Debian", "Fedora",
"CrunchBang", "Backtrack", "Puppy Linux", "OpenBSD", "Slackware",
"BlankOn", "CentOS" };
private String[] pilihan_menu = { "Tambah Data", "Edit Data", "Hapus Data",
"Kirim Data" };
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Arrays.sort(Distro);
ListView list = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, Distro);
list.setAdapter(adapter);
registerForContextMenu(list);
}
public void onCreateContextMenu(ContextMenu menu, View tampil,
ContextMenuInfo menuInfo) {
if (tampil.getId() == R.id.list) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
menu.setHeaderTitle(Distro[info.position]);
for (int i = 0; i < pilihan_menu.length; i++) {
menu.add(Menu.NONE, i, i, pilihan_menu[i]);
}
}
}
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
String aksi = pilihan_menu[item.getItemId()];
String nama_pilihan = Distro[info.position];
String isi = String.format("Anda melakukan operasi %s pada pilihan %s",
aksi, nama_pilihan);
Toast.makeText(this, isi, Toast.LENGTH_LONG).show();
return true;
}
}
Its work perfectly showing contextmenu for long click. I changed the code to implement the onclick to be able to open a context menu with a short click.
public class ListConActivity extends Activity implements OnClickListener {
private String[] Distro = { "Ubuntu", "Arch Linux", "Mandriva",
"Open Suse", "IGOS Nusantara", "Linux Mint", "Debian", "Fedora",
"CrunchBang", "Backtrack", "Puppy Linux", "OpenBSD", "Slackware",
"BlankOn", "CentOS" };
private String[] pilihan_menu = { "Tambah Data", "Edit Data", "Hapus Data",
"Kirim Data" };
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Arrays.sort(Distro);
ListView list = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, Distro);
list.setAdapter(adapter);
registerForContextMenu(list);
list.setOnClickListener(this);
}
public void onCreateContextMenu(ContextMenu menu, View tampil,
ContextMenuInfo menuInfo) {
if (tampil.getId() == R.id.list) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
menu.setHeaderTitle(Distro[info.position]);
for (int i = 0; i < pilihan_menu.length; i++) {
menu.add(Menu.NONE, i, i, pilihan_menu[i]);
}
}
}
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
String aksi = pilihan_menu[item.getItemId()];
String nama_pilihan = Distro[info.position];
String isi = String.format("Anda melakukan operasi %s pada pilihan %s",
aksi, nama_pilihan);
Toast.makeText(this, isi, Toast.LENGTH_LONG).show();
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
openContextMenu(v);
}
}
Compile success.. But i get force close. Can u help me? thanks dude!
You have set click listener for ListView, not list items. Use setOnItemClickListener and AdapterView.OnItemClickListener
yeaH: do a setOnItemClickListener for listView & in that click method call openContextMenu(view) from Activity class
setListAdapter(new ArrayAdapter<String>(this,R.layout.custom_list_item, r));
protected void onListItemClick(ListView list, View view, int position, long id) {
super.onListItemClick(list, view, position, id);
fname=r.get(position);
the above code I got position and name also from array adapter
Like, I need get these all are the values in context menu how can I get it
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Playlist Option");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
public boolean onContextItemSelected(MenuItem item) {
// here I select the particular list value, that the value position I need that is only I delete that position from server. what are the data i fetch here? and its possible to get position from array list?
}
You can use AdapterContextMenuInfo
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.delete:
String itemName = r.get[(int) info.id]; // This item you will delete
// from list
return true;
}
}
public class DataDemo extends Activity {
public ArrayList<HashMap<String, String>> ContactList = new ArrayList<HashMap<String, String>>();
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_PHNO = "phNo";
private static int itemIndex;
private ListView lst;
private List<Contact> contacts;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_database_demo);
lst = (ListView) findViewById(R.id.lstContact);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId() == R.id.lstContact) {
menu.setHeaderIcon(R.drawable.message);
menu.setHeaderTitle("Contacts");
menu.add(0, 1, Menu.NONE, "Edit Contact");
menu.add(0, 2, Menu.NONE, "Delete Contact");
menu.add(0, 3, Menu.NONE, "Cancel");
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
AdapterView.AdapterContextMenuInfo menuInfo;//you can select on context item selected
menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
itemIndex = menuInfo.position;//you will get position of selected item
final Contact con = contacts.get(itemIndex);
switch (item.getItemId()) {
case 1:
Intent editIntent = new Intent(DataDemo.this, UpdateContact.class);
editIntent.putExtra(TAG_ID, con.getID());
editIntent.putExtra(TAG_NAME, con.getName());
editIntent.putExtra(TAG_PHNO, con.getPhNo());
startActivity(editIntent);
break;
case 2:
new AlertDialog.Builder(this)
.setIcon(R.drawable.document_delete)
.setTitle("Confirm Delete")
.setMessage("Are you sure?")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
DatabaseHandler db = new DatabaseHandler(
DataDemo.this);
db.DeleteContact(con);
Toast.makeText(DataDemo.this, con.getName() + " Deleted",
Toast.LENGTH_SHORT).show();
fillList();
}
}).setNegativeButton("No", null).show();
break;
default:
break;
}
return super.onContextItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem addNew = menu.add(0, 1, 0, "Create Contact");
addNew.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// TODO Auto-generated method stub
Intent iCreate = new Intent(DataDemo.this, CreateContact.class);
startActivity(iCreate);
return true;
}
});
return true;
}
protected void fillList() {
DatabaseHandler db = new DatabaseHandler(this);
ListAdapter adap;
ContactList.clear();
contacts = db.ReadAllContact();
for (Contact cn : contacts) {
HashMap<String, String> hmap = new HashMap<String, String>();
hmap.put(TAG_NAME, cn.getName());
hmap.put(TAG_PHNO, cn.getPhNo());
ContactList.add(hmap);
adap = new SimpleAdapter(this, ContactList,
R.layout.list_item_view,
new String[] { TAG_NAME, TAG_PHNO }, new int[] {
R.id.lstName, R.id.lstPhNo });
lst.setAdapter(adap);
registerForContextMenu(lst);
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
fillList();
}
}
on my deleteLogItem i need to pass teh listView so i can find the item in position(id) to delete him.
how can i pass it to him.
import com.parse.FindCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
public class LogActivity extends ListActivity {
private static final int DELETE_ID = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Parse.initialize(this, "sjfsjdfhjshfjhsjdfhsjhfjshdf4",
"sdfgsdfgsdfg76sdfg76s7dfgsd");
final ProgressDialog dialog = ProgressDialog.show(LogActivity.this, "",
"Loading. Please wait...", true);
ParseQuery query = new ParseQuery("Devices");
query.whereEqualTo("Device", "ffffffff-e0d7-1802-8031-65e37f7a7ed3");
query.findInBackground(new FindCallback() {
public void done(List<ParseObject> scoreList, ParseException e) {
if (e == null) {
initListView(scoreList);
dialog.dismiss();
} else {
objectRetrievalFailed();
}
}
});
}
protected void objectRetrievalFailed() {
// TODO Auto-generated method stub
}
private void initListView(List<ParseObject> objects) {
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(
2);
HashMap<String, String> map;
for (ParseObject hashMap : objects) {
map = new HashMap<String, String>();
map.put("line0", hashMap.getObjectId());
map.put("line1", hashMap.getString("Model"));
map.put("line2", hashMap.getString("Device"));
map.put("line3", (String) hashMap.getCreatedAt().toString());
list.add(map);
}
// the from array specifies which keys from the map
// we want to view in our ListView
String[] from = { "line1", "line2", "line3" };
// the to array specifies the TextViews from the xml layout
// on which we want to display the values defined in the from array
int[] to = { R.id.item_title, R.id.item_subtitle, R.id.item_subtitle2 };
// create the adapter and assign it to the listview
SimpleAdapter adapter = new SimpleAdapter(this, list,
R.layout.first_list, from, to);
setListAdapter(adapter);
registerForContextMenu(getListView());
}
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, "Delete");
}
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
switch (item.getItemId()) {
case DELETE_ID:
deleteLogItem(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}
private void deleteLogItem(long id) {
// TODO Auto-generated method stub
HashMap<String, String> o = (HashMap<String, String>) l
.getItemAtPosition((int)id);
// String selection = l.getItemAtPosition(position).toString();
String selection = o.get("line0");
Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
}
}
EDIT: i just add the line ListView l = getListView();