Reputation: 4386
I have a custom list adapter. Here it is:
public class FilesAdapter extends ArrayAdapter<PutioFileLayout> {
Context context;
int layoutResourceId;
List<PutioFileLayout> data = null;
public FilesAdapter(Context context, int layoutResourceId, List<PutioFileLayout> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
FileHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new FileHolder();
holder.textName = (TextView) row.findViewById(R.id.text_fileListName);
holder.textDescription = (TextView) row.findViewById(R.id.text_fileListDesc);
holder.imgIcon = (ImageView) row.findViewById(R.id.img_fileIcon);
row.setTag(holder);
} else {
holder = (FileHolder) row.getTag();
}
PutioFileLayout file = data.get(position);
holder.textName.setText(file.name);
holder.textDescription.setText(file.description);
holder.imgIcon.setImageResource(file.icon);
return row;
}
static class FileHolder {
TextView textName;
TextView textDescription;
ImageView imgIcon;
}
}
Pretty short and sweet. I have Spinner
s in my layout for each row, and I want the user to be able to click them, and get a contextual menu for each item. How can I implement this in my adapter?
My row.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="64dp" >
<ImageView
android:id="@+id/img_fileIcon"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/img_fileIcon"
android:orientation="vertical" >
<TextView
android:id="@+id/text_fileListName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="12dp"
android:ellipsize="end"
android:maxLines="1"
android:text="File name"
android:textAppearance="?android:attr/textAppearanceMedium" />
<FrameLayout
android:id="@+id/descriptionFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="30dp" >
<TextView
android:id="@+id/text_fileListDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="File description" />
</FrameLayout>
</LinearLayout>
<Spinner
android:id="@+id/item_fileSpinner"
android:layout_width="44dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/spinner_background_ab_putio" />
</RelativeLayout>
Upvotes: 3
Views: 5243
Reputation: 6620
why can't you use createContextMenu() ? in case you can, override onContextCreate() and add your view IDs there....
I don't have sample code atm, but I will when i get to the office on monday. Really, context menus are the easiest way to do it.
Then again, tim's idea seems to have did the trick.
EDIT: as promised on monday, sample code.
res\menu\context_menu.xml -- note that you can change this name.
<item
android:id="@+id/context_menu_call"
android:title="@string/context_menu_call"/>
<item
android:id="@+id/context_menu_video_call"
android:title="@string/context_menu_video_call"/>
<item
android:id="@+id/context_menu_send_im"
android:title="@string/context_menu_send_im"/>
<item
android:id="@+id/context_menu_call_number"
android:title="@string/context_menu_call_number"/>
<item
android:id="@+id/context_menu_view_profile"
android:title="@string/context_menu_view_profile"/>
then in code
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
switch (v.getId())
{
case R.id.listConversations: //mainContactList from initMainLayoutElements()
contextList = mainContactList;
inflater.inflate(R.menu.context_menu, menu);
break;
case R.id.listContacts: //chatContacts from initChatLayoutElements()
contextList = chatContactList;
inflater.inflate(R.menu.context_menu, menu);
break;
case R.id.listContactsManagement: //contactList from initContactLayoutElements()
contextList = contactMgmtList;
inflater.inflate(R.menu.context_menu, menu);
break;
case R.id.btn_sms_settings:
inflater.inflate(R.menu.sms_menu, menu);
break;
}
}
now that we defined how to open context menus, we need to define what the actual items do...
@Override
public boolean onContextItemSelected(MenuItem item)
{
item.getMenuInfo();
switch (item.getItemId())
{
case R.id.context_menu_call:
onCallStartFromContextMenu(false);
return true;
case R.id.context_menu_video_call:
onCallStartFromContextMenu(true);
return true;
case R.id.context_menu_send_im:
layoutState(LayoutState.CHAT);
Log.d(TAG, "Preparing chat session from context menu for " + getChattersFromList(contextList).toString());
chatSource = ChatSource.FROM_CONTEXT_MENU;
prepareChatSessionWith(getChattersFromList(contextList).toArray(new String[getChatterCount(contextList)]));
return true;
case R.id.context_menu_call_number:
Buddy selectedBuddy = (Buddy) contextList.getAdapter().getItem(contextList.getSelectedItemPosition());
lastCaller = selectedBuddy.toString();
showAlternateCallDialog(selectedBuddy, !selectedBuddy.getNumberHome().isEmpty(),
!selectedBuddy.getNumberMobile().isEmpty(), !selectedBuddy.getNumberOffice().isEmpty());
return true;
case R.id.context_menu_view_profile:
// Buddy who = buddyAdapter.getItem(listConversations.getSelectedItemPosition());
Buddy who = (Buddy) contextList.getAdapter().getItem(contextList.getSelectedItemPosition());
Log.d(TAG, "viewing profile " + who.toString());
lastProfileName = who.getIdentity();
showProfileScreen(who);
return true;
//transfers
default:
contextList = null;
return super.onContextItemSelected(item);
}
}
don't forget to register the component to the context menu 'listener'. These are actual ListView references.
registerForContextMenu(mainContactList);
registerForContextMenu(chatContactList);
and finally, the only thing left is OPENING the context menus for items...
chatContactList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
Log.d(TAG, "chatContacts.onItemLongClick fired!");
chatContactList.setItemChecked(position, true);
openContextMenu(chatContactList);
return true;
}
});
mainContactList.setOnItemLongClickListener(new ListView.OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
Log.d(TAG, "mainContactList.onItemLongClick fired!!!");
mainContactList.setItemChecked(position, true);
openContextMenu(mainContactList);
return false;
}
});
i prefer using context menus on LongClick instead of just onItemClicked because you might wanna do something on clicking (like, file selection and stuff) and offer less-accessed functionalities on a long click like rename / delete etc
so there you go. context menus are easy ;)
Upvotes: 2
Reputation: 46856
Inside your getView() method get a reference to the spinner like this:
Spinner spn = row.findViewById(R.id.item_fileSpinner);
once you have the reference you can set its items by creating a SpinnerAdapter with all of your values and set it with
spn.setAdapater(mSpinAdapter);
I can give you a more specific example of how you'd create and fill your adapter if you can tell me what data you are hoping to fill the spinner with.
then all thats left is to set an OnItemSelectedListener, which you can do like this.
spn.setOnItemSelectedListner(new OnItemSelectedListener(){
public void onItemSelected(AdapterView<?> parent, View view, int spnPosition, long id){
//Do something
}
});
Note the use of spnPosition
in the onItemSelected callback. If you use position
then you will no longer have access to the getView() parameter position
so use a different name so that you can access both/either if needbe.
Upvotes: 2