BaseAdapter and ContextMenu - android

Hello stackoverflow community,
Basically, i have gallery displaying some images using a gridView + imageView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<GridView android:id="#+id/PhoneImageGrid"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:numColumns="auto_fit" android:verticalSpacing="12dp"
android:horizontalSpacing="12dp" android:columnWidth="90dp"
android:stretchMode="columnWidth" android:gravity="center" />
<ImageView android:id="#+id/thumbImage" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_centerInParent="true"
android:scaleType="centerCrop"
/>
I would like to use setOnLongClick for each imageView displayed by the adapter.
This works well, however, when clicking long on the imageView, i would like to display a ContextMenu with some items ( i.e, you long click on an imageView, a contextMenu is displayed with some items : Image information, send this image ...).
Unfortunatly, i can't figure out how to inflate this menu in the adapter.(Probably not the good way to do it )
I have the following lines in my main activity
_adapter = new ImageAdapter(activity,storedObjects.getAlbums());
imagegrid.setAdapter(_adapter);
My adapter ( some useless lines removed )
public class ImageAdapter extends BaseAdapter {
private Albums albums;
private Context context;
private LayoutInflater inflater;
public ImageAdapter(Context context, Albums albums) {
this.albums = albums;
this.context = context;
inflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
if(albums.getAlbumsListSize() == 0) {
Toast.makeText(context, "There is no album to display", Toast.LENGTH_LONG).show();
}
}
public View getView(final int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.galleryitem, null);
holder.imageview = (ImageView) view.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) view.findViewById(R.id.itemCheckBox);
holder.textview = (TextView) view.findViewById(R.id.album_name);
holder.checkbox.setChecked(true);
//Bitmap loadingBM = BitmapFactory.decodeResource(context.getResources(),R.drawable.loading_image);
//holder.imageview.setImageBitmap(loadingBM);
view.setTag(holder);
}
else {
holder = (ViewHolder) view.getTag();
}
holder.imageview.setClickable(true);
holder.imageview.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v) {
Log.v(TAG,"onLongClick ok !");
return false;
}
});
imageDownloader.download(this.context, albums.getAllAlbums().get(position).getThumbnailUri(), holder.imageview);
return view;
}
Questions :
setOnLongClickListener works properly, when i click on an image, my Log is displayed in logcat, however, how to create a menu for each imageView ?
Apparently, i can only override onCreateContextMenu in my main activity. I guess i could pass each ImageView to onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) but how ?
I would be really grateful if you could help me out with this.
Thank you very much
Florent Valdelievre

Instead of setOnLongClickListener on the ImageView, call registerForContextMenu with your GridView. Then, implement onCreateContextMenu and onContextItemSelected.
Here is a simple ListActivity to show you how it works.
public class GreetingActivity extends ListActivity {
private static final String[] mGreetings = { "Hello", "Goodbye" };
private static final String[] mPeople = { "Alice", "Bob", "Charlie" };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mPeople);
setListAdapter(adapter);
ListView listView = getListView();
registerForContextMenu(listView);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
for (int i = 0; i < mGreetings.length; ++i) {
String greeting = mGreetings[i];
menu.add(v.getId(), i, ContextMenu.NONE, "Say " + greeting);
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo menuInfo
= (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int adapterPosition = menuInfo.position;
String person = mPeople[adapterPosition];
int menuItemId = item.getItemId();
String greeting = mGreetings[menuItemId];
String msg = String.format("%s, %s!", greeting, person);
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
return true;
}
}

Thank you so much #chiuki, it works as expected
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
final GridView imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);
registerForContextMenu(imagegrid);
storedObjects.storeThumbnailsURI();
_adapter = new ImageAdapter(activity,storedObjects.getAlbums());
imagegrid.setAdapter(_adapter);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
Log.v("context menu","context menu");
menu.setHeaderTitle("Context Menu");
menu.add(0, START_SLIDESHOW_ON_THIS_ALBUM, 0, "Start SlideShow for this Album");
menu.add(0, DOWNLOAD_WHOLE_ALBUM, 0, "Download this Album");
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case START_SLIDESHOW_ON_THIS_ALBUM:
selectThisAlbumOnly(info);
startSlideShow();
break;
case DOWNLOAD_WHOLE_ALBUM:
break;
}
return true;
}
In the Adapter, make sure you don't have any setClickable = true
Cheers
Florent

Related

Fragment Context Menu Notify Adapter

I have a ListView within a Fragment. I have been trying to setup a functional ContextMenu to delete and edit entries. Simply passing saveAdapter.notifyDataSetChanged(); returns null. Passing ArrayAdapter<LiftSave> saveAdapter = new SaveListAdapter(); results in a message:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes.
I'd greatly appreciate any insight into resolving the adapter, and/or any advice to the best practice for the of setup the edit option. Perhaps launching a custom AlertDialog? Thanks in advance.
Fragment:
public static class FragmentS extends Fragment {
private ListView saveListView;
private List<LiftSave> LiftSaves = new ArrayList<LiftSave>();
private static final int EDIT = 0, DELETE = 1;
int longClickedItemIndex;
DatabaseHandler dbHandler;
ArrayAdapter<LiftSave> saveAdapter;
public FragmentS() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listview_s,
container, false);
saveListView = (ListView) rootView.findViewById(R.id.saveListView);
registerForContextMenu(saveListView);
DatabaseHandler dbHandler;
dbHandler = new DatabaseHandler (getActivity().getApplicationContext());
if (dbHandler.getLiftSavesCount() != 0)
LiftSaves.addAll(dbHandler.getAllLiftSaves());
populateList();
saveListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
longClickedItemIndex = position;
return false;
}
});
return rootView;
}
private void populateList() {
ArrayAdapter<LiftSave> saveAdapter = new SaveListAdapter();
saveListView.setAdapter(saveAdapter);
}
public class SaveListAdapter extends ArrayAdapter<LiftSave> {
public SaveListAdapter() {
super(getActivity(), R.layout.listview_item, LiftSaves);
}
#Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null)
view = getActivity().getLayoutInflater().inflate(R.layout.listview_item, parent, false);
LiftSave currentLiftSave = LiftSaves.get(position);
TextView liftName = (TextView) view.findViewById(R.id.liftName);
liftName.setText(currentLiftSave.getLiftName());
TextView maxValue = (TextView) view.findViewById(R.id.maxValue);
maxValue.setText(currentLiftSave.getMaxValue());
TextView weightAndReps = (TextView) view.findViewById(R.id.weightAndReps);
weightAndReps.setText(currentLiftSave.getRepsAndWeight());
TextView liftNotes = (TextView) view.findViewById(R.id.liftNotes);
liftNotes.setText(currentLiftSave.getLiftNotes());
TextView date = (TextView) view.findViewById(R.id.todayDate);
date.setText(currentLiftSave.getTodayDate());
return view;
}
}
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
menu.setHeaderIcon(R.drawable.pencil_icon);
menu.setHeaderTitle("Save Options");
menu.add(Menu.NONE, EDIT, menu.NONE, "Edit Save");
menu.add(Menu.NONE, DELETE, menu.NONE, "Delete Save");
}
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case EDIT:
// TODO: Add save edit code
break;
case DELETE:
dbHandler = new DatabaseHandler (getActivity().getApplicationContext());
dbHandler.deleteLiftSave(LiftSaves.get(longClickedItemIndex));
LiftSaves.remove(longClickedItemIndex);
saveAdapter.notifyDataSetChanged();
break;
}
return super.onContextItemSelected(item);
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TabbedActivity$FragmentS"
android:background="#android:color/holo_blue_dark">
<LinearLayout
android:id="#+id/tabSaveList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Saved Maxes"
android:id="#+id/textView"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:textColor="#fffaf4a1"
android:textStyle="bold" />
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/saveListView" />
</LinearLayout>
</RelativeLayout>
change int longClickedItemIndex; to be LiftSave longClickedItemLiftSave;
Then in the long press listener capture that value as longClickedItemLiftSave:
saveListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
longClickedItemLiftSave = (LiftSave) parent.getItemAtPosition(position);
return false;
}
});
then in your menu handling just call ArrayAdapter#remove(T), this will call notifyDataSetChanged for you
case DELETE:
dbHandler = new DatabaseHandler (getActivity().getApplicationContext());
dbHandler.deleteLiftSave(longClickedItemLiftSave);
saveAdapter.remove(longClickedItemLiftSave);
break;
finally, change your populateList so it uses the fragment's field of saveAdapter instead of a local var to this method only.
private void populateList() {
saveAdapter = new SaveListAdapter();
saveListView.setAdapter(saveAdapter);
}

How to implement checkbx with custom listview

   I want to make product list with their price,name,image and checkbox,
User checks the product as the user wants and then pass it to second activity,
       
 In second activity it display the item checked with their price,So what method i have to use specially for checkbox input,I am newbie to android so please help me,
I suppose you have a class Product with price, name ...
You have to create a layout (list_row.xml) with the format that you want, for example:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="?android:attr/activatedBackgroundIndicator"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv_subtitle_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/tv_title_list"
android:layout_below="#+id/tv_title_list"
android:longClickable="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_title_list"
android:longClickable="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignRight="#+id/tv_title_list"
android:layout_alignBottom="#+id/tv_title_list"
android:id="#+id/img_sync"
android:longClickable="true" />
</RelativeLayout>
After that, you need a List Adapter, the best way is create a Custom List adapter
public class ProductListAdapter extends ArrayAdapter<Product>
{
private List<Product> objects;
private Context context;
public ProductListAdapter(Context context, int textViewResourceId, List<Product> objects)
{
super(context, textViewResourceId, objects);
this.context = context;
this.objects = objects;
}
#Override
public int getCount() {
return objects.size();
}
#Override
public Incidence getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
if(objects.get(position)==null) return -1;
return objects.get(position).getId(); // your database id
}
#Override
public void addAll(Collection<? extends Product> objects) {
this.objects= new ArrayList<>(objects);
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
Incidence rowItem = getItem(position); // get selected item
if (convertView == null)
{
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_row, null);
}
/* Access to row components */
TextView title = (TextView) convertView.findViewById(R.id.tv_title_list); // name
TextView subtitle = (TextView) convertView.findViewById(R.id.tv_subtitle_list); // price
ImageView img = (ImageView) convertView.findViewById(R.id.img_sync); // image
title.setText(rowItem.getName());
subtitle.setText(rowItem.getPrice());
img.setImageResource(android.R.drawable.ic_menu_share);
return convertView;
}
}
In your fragment or activity you create the adapter:
public class FragListIncidences extends ListFragment
{
public void initUI() // include this in your onCreate
{
mAdapter = new ProductListAdapter(getActivity(),
android.R.layout.simple_list_item_1, new ArrayList<Product>());
setListAdapter(mAdapter); // because of ListFragment
}
}
The checkbox functionality that you want can be implemented in two ways:
Add Cechbox component in your list_row.xml
You can use a contextual action mode menu. Here you have an example http://developer.android.com/intl/es/guide/topics/ui/menus.html#CAB
public void initUI() // include this in your onCreate
{
mAdapter = new ProductListAdapter(getActivity(),
android.R.layout.simple_list_item_1, new ArrayList<Product>());
setListAdapter(mAdapter); // because of ListFragment
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener()
{
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
final int checkedCount = mListView.getCheckedItemCount();
mode.setTitle(checkedCount + " Selected");
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.action_get:
getSelectedItems();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
return false;
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate the menu for the CAB
MenuInflater inflater = mode.getMenuInflater();
contextual_menu =menu;
inflater.inflate(R.menu.subactions, menu);
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// Here you can make any necessary updates to the activity when
// the CAB is removed. By default, selected items are deselected/unchecked.
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Here you can perform updates to the CAB due to
// an invalidate() request
return false;
}
});
}
private void getSelectedItems() {
final SparseBooleanArray selected = mListView.getCheckedItemPositions();
for (int i = (selected.size() - 1); i >= 0; i--)
if (selected.valueAt(i))
doWhateverYouWant (selected.keyAt(i));
}
In java you have to instantiate each checkBox that you put into your layouts (i.e. CheckBox checkbox1 = new (Checkbox) findViewById(R.id.checkbox1);
Then all you have to do is put a few if() statements into your onCreate like this:
if(checkbox1.isChecked == true){
//send the info to your next activity
}else{
//nothing
}

How to open Menu Context Android with click button in listview adapter?

How to open Menu Context Android with click button in listview adapter ?
I tried with my code, but not show the menu context,
code
public View getView(int position, View convertView, ViewGroup parent) {
vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.tulisan_komentar_list_item,parent, false);
LinearLayout content_favorite= (LinearLayout)vi.findViewById(R.id.content_favorite);
final TextView date_komentar = (TextView)vi.findViewById(R.id.date_komentar); // artist name
final TextView isi_komentar = (TextView)vi.findViewById(R.id.isi_komentar); // duration
final TextView nama_komentar = (TextView)vi.findViewById(R.id.nama_komentar); // duration
final TextView id_tulisan_komentar = (TextView)vi.findViewById(R.id.id_tulisan_komentar); // duration
final ImageButton act_komentar = (ImageButton)vi.findViewById(R.id.act_komentar);
ImageView thumb_image=(ImageView)vi.findViewById(R.id.avatar_komentar); // thumb image
HashMap<String, String> tulisan = new HashMap<String, String>();
tulisan = data.get(position);
// Setting all values in listview
date_komentar.setText(tulisan.get(ContentCommentActivity.TAG_DATE_KOMENTAR));
isi_komentar.setText(tulisan.get(ContentCommentActivity.TAG_ISI_KOMENTAR));
nama_komentar.setText(tulisan.get(ContentCommentActivity.TAG_NAMA_KOMENTAR));
id_tulisan_komentar.setText(tulisan.get(ContentCommentActivity.TAG_ID_TULISAN_KOMENTAR));
String avatar_komentar = tulisan.get(ContentCommentActivity.TAG_AVATAR_KOMENTAR);
if(hide_gambar.equals("Y")){
thumb_image.setVisibility(View.GONE);
}
else{
thumb_image.setVisibility(View.GONE);
/* thumb_image.setVisibility(View.VISIBLE);
if (avatar_komentar.equals("")) {
thumb_image.setVisibility(View.GONE);
} else {
imageLoader.DisplayImage(tulisan.get(ContentCommentActivity.TAG_AVATAR_KOMENTAR), thumb_image);
thumb_image.setVisibility(View.VISIBLE);
} */
}
activity.registerForContextMenu(act_komentar);
act_komentar.setOnClickListener(new android.view.View.OnClickListener()
{
public void onClick(View v)
{
activity.openContextMenu(v);
v.showContextMenu();
}
});
return vi;
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
menu.setHeaderTitle("My Context Menu");
menu.add(0, 1, 0, "Add");
menu.add(0, 2, 0, "Edit");
menu.add(0, 3, 1, "Delete");
}
can you tell me, how it should work ?
Use like this:
act_komentar.setOnClickListener(new android.view.View.OnClickListener() {
public void onClick(View v) {
//To register the button with context menu.
registerForContextMenu(act_komentar);
openContextMenu(act_komentar);
}
});
final int CONTEXT_MENU_VIEW = 1;
final int CONTEXT_MENU_EDIT = 2;
final int CONTEXT_MENU_ARCHIVE = 3;
#Override
public void onCreateContextMenu (ContextMenu menu, View
v, ContextMenu.ContextMenuInfo menuInfo){
//Context menu
menu.setHeaderTitle("My Context Menu");
menu.add(Menu.NONE, CONTEXT_MENU_VIEW, Menu.NONE, "Add");
menu.add(Menu.NONE, CONTEXT_MENU_EDIT, Menu.NONE, "Edit");
menu.add(Menu.NONE, CONTEXT_MENU_ARCHIVE, Menu.NONE, "Delete");
}
#Override
public boolean onContextItemSelected (MenuItem item){
// TODO Auto-generated method stub
switch (item.getItemId()) {
case CONTEXT_MENU_VIEW: {
}
break;
case CONTEXT_MENU_EDIT: {
// Edit Action
}
break;
case CONTEXT_MENU_ARCHIVE: {
}
break;
}
return super.onContextItemSelected(item);
}
Output:
Hope this will work for you.
The accepted answer is really not optimal - it may simply be dated.
button.setOnCreateContextMenuListener((menu, v, menuInfo) -> {
final MenuItem item = menu.add("item-text");
item.setOnMenuItemClickListener(i -> {
doWorkOnItemClick();
return true; // Signifies you have consumed this event, so propogation can stop.
});
final MenuItem anotherItem = menu.add("another-item");
anotherItem.setOnMenuItemClickListener(i -> doOtherWorkOnItemClick());
});
button.setOnClickListener(View::showContextMenu);
Alternatively you can show the context menu in a specific location like so:
button.setOnClickListener(view -> view.showContextMenu(x, y));

when to use adapter and when to use inflater

I'm newbie in Android and i learning context menu but after surfing about context menu i have little bit confusion in Adapter and Inflater. I saw 1 program with using adapter and 1 using Inflater. So, please help me how/when to use Adapter and Inflater.
Here is an example using inflater...
public class MainActivity extends ListActivity {
private String selectedName = "";
private String[] nameList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
nameList = getResources().getStringArray(R.array.name_list);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, nameList));
registerForContextMenu(getListView());
}
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
getMenuInflater().inflate(R.menu.context_menu, menu);
}
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo adapInfo = (AdapterContextMenuInfo) item
.getMenuInfo();
selectedName = nameList[(int) adapInfo.id];
switch (item.getItemId()) {
case R.id.view:
Toast.makeText(MainActivity.this,
"You have pressed View Context Menu for " + selectedName,
Toast.LENGTH_LONG).show();
return true;
case R.id.save:
Toast.makeText(MainActivity.this,
"You have pressed Save Context Menu for " + selectedName,
Toast.LENGTH_LONG).show();
return true;
case R.id.edit:
Toast.makeText(MainActivity.this,
"You have pressed Edit Context Menu for " + selectedName,
Toast.LENGTH_LONG).show();
return true;
case R.id.delete:
Toast.makeText(MainActivity.this,
"You have pressed Delete Context Menu for " + selectedName,
Toast.LENGTH_LONG).show();
return true;
}
return false;
}
}
Another example using adapter:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Countries = getResources().getStringArray(R.array.Game);
ListView list = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.listitem, Countries);
list.setAdapter(adapter);
registerForContextMenu(list);
}
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
if (v.getId() == R.id.list) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
menu.setHeaderTitle(Countries[info.position]);
String[] menuItems = getResources().getStringArray(
R.array.contextmenu);
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
}
}
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
int menuItemIndex = item.getItemId();
String[] menuItems = getResources().getStringArray(R.array.contextmenu);
String[] menuItems1 = getResources().getStringArray(R.array.game);
String menuItemName = menuItems[menuItemIndex];
String listItemName = menuItems1[info.position];
// selectedName = nameList[(int) info.id];
TextView text = (TextView) findViewById(R.id.textView1);
text.setText(String.format("Selected %s for item %s", menuItemName,
listItemName));
return true;
}
These types serve different purposes.
The MenuInflator converts XML files into a Menu object representing the on-screen layout of the menu. In the first example, R.menu.context_menu refers to an associated XML file at res/menu/context_menu.xml that defines the choices that will appear in the menu. See Menu Resource for the format of XML menu resources. Here's a simple example:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/open" android:title="Open"/>
<item android:id="#+id/info" android:title="More Info"/>
<item android:id="#+id/delete" android:title="Delete"/>
</menu>
The AdapterContextMenuInfo provides extra information when a context menu is brought up for a list, grid, etc. It allows you to determine which item the user selected (long pressed). Notice that both of your examples use this.

Making a custom android ListView adapter Clickable

I've been trying to create a clickable listview that takes in a string array and a few images and presents them in a textview style. So far I have managed to create a listview with each of the strings and images, however I am unsure how to use the onClick method so as to make the textviews clickable to start new activities etc.
Here is my code so far (Excluding XML):
public class MySimpleArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public MySimpleArrayAdapter(Context context, String[] values) {
super(context, R.layout.activity_test2, values);
this.context = context;
this.values = values;
}
/* Print a toast when a list item is clicked, don't know what to do */
public void onClick() {
switch (list item) {
case 0:
Toast.makeText(this.context, "Pressed!", Toast.LENGTH_LONG).show()
break;
}
case 1:
etc....
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.activity_test2, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
textView.setText(values[position]);
String s = values[position];
if (s.startsWith("Report a Road Delay")) {
imageView.setImageResource(R.drawable.ic_menu_compose);
} else if (s.startsWith("View Reported Delays")) {
imageView.setImageResource(R.drawable.ic_menu_view);
} else if (s.startsWith("Search a Road for Delays")) {
imageView.setImageResource(R.drawable.ic_menu_search);
} else if (s.startsWith("Update a Delay Report")) {
imageView.setImageResource(R.drawable.ic_menu_edit);
} else if (s.startsWith("Validate a Delay Report")) {
imageView.setImageResource(R.drawable.ic_menu_mark);
}
return rowView;
}
}
public class MainActivity extends ListActivity {
public void onCreate(Bundle SavedInstanceState) {
super.onCreate(SavedInstanceState);
String[] values = new String[] { "Report a Road Delay",
"View Reported Delays", "Search a Road for Delays",
"Update a Delay Report", "Validate a Delay Report" };
MySimpleArrayAdapter adapter = new MySimpleArrayAdapter(this, values);
setListAdapter(adapter);
}
}
This is how it looks so far:
All I basically don't understand is the onClick method; what parameters it takes it, and how to determine which item was clicked. Any help would be appreciated.
Try this:
ListView list1 = getListView();
list1.setOnItemClickListener(
new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
//Take action here.
}
}
);
You are looking for an OnItemClickListener and not an OnClickListener
lv.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// DO SOMETHING WITH CICK EVENT HERE
}
}
Now only to discus the params:
parent The AdapterView where the click happened.
view The view within the AdapterView that was clicked
position The position of the view in the adapter.
id The row id of the item that was clicked.
I got the last part from android reference
You could use this code:
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parentAdapter, View view, int position,
long id) {
// We know the View is a <extView so we can cast it
TextView clickedView = (TextView) view;
Toast.makeText(MainActivity.this, "Item with id ["+id+"] - Position ["+position+"] - Planet ["+clickedView.getText()+"]", Toast.LENGTH_SHORT).show();
}
});
// we register for the contextmneu
registerForContextMenu(lv);
}
where lv is the listView.
If you want to add a context menu:
// We want to create a context Menu when the user long click on an item
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;
// We know that each row in the adapter is a Map
Planet planet = aAdpt.getItem(aInfo.position);
menu.setHeaderTitle("Options for " + planet.getName());
menu.add(1, 1, 1, "Details");
menu.add(1, 2, 2, "Delete");
}
// This method is called when user selects an Item in the Context menu
#Override
public boolean onContextItemSelected(MenuItem item) {
int itemId = item.getItemId();
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) item.getMenuInfo();
planetsList.remove(aInfo.position);
aAdpt.notifyDataSetChanged();
return true;
}
If you want to have more information give a look on my blog here and here

Categories

Resources