I am trying to display a context menu on clicking item in a recycler view, and the choose to call the person whose name has been clicked. But I am unable to retrieve the phone number because the getMenuInfo() is not working bcoz I am getting a null in contextMenuInfo in onCreateContextMenu(). I have referenced many answers and written my code accordingly but still not able to correct it Here is my code:
menu_actions.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/call"
android:title="Call">
</item>
<item
android:id="@+id/sms"
android:title="Send SMS">
</item>
<item
android:id="@+id/email"
android:title="Send email">
</item>
<item
android:id="@+id/viewContact"
android:title="View Details">
</item>
<item
android:id="@+id/editContact"
android:title="Edit Contact">
</item>
<item
android:id="@+id/deleteContact"
android:title="Delete">
</item>
</menu>
My fragment which contains the recycler view:
public class MyContacts extends Fragment {
public static RecyclerView recyclerView;
public static Person receivedData;
static Context c;
static int itemIndex;
DatabaseAdapter dbAdapter = new DatabaseAdapter(getContext());
private static RecyclerViewAdapter recyclerViewAdapter;
ArrayList<Person> persons = new ArrayList<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
c = getContext();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
MainActivity activity = (MainActivity) getActivity();
receivedData = activity.getData();
View layout = inflater.inflate(R.layout.fragment_my_contacts, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.myContactsList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerViewAdapter=new RecyclerViewAdapter(activity, persons);
recyclerView.setAdapter(recyclerViewAdapter);
registerForContextMenu(recyclerView);
retrieve();
return layout;
}
public void retrieve()
{
persons.clear();
DatabaseAdapter databaseAdapter = new DatabaseAdapter(c);
databaseAdapter.openDB();
//retrieves the whole table from DB
Cursor cursor = databaseAdapter.getDataForList();
// loop and add to array list
while (cursor.moveToNext())
{
int index1 = cursor.getColumnIndex(Constants.PHONE);
String name = cursor.getString(index1);
......
Person p = new Person(name, phone, address, email, dob, R.id.contactImage);
persons.add(p);
}
//if array list not empty
if (!(persons.size() <1))
{
recyclerViewAdapter.notifyDataSetChanged();
}
databaseAdapter.closeDB();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) // here menuInfo is coming NULL
{
super.onCreateContextMenu(menu, view, menuInfo);
getActivity().getMenuInflater().inflate(R.menu.menu_actions, menu);
menu.setHeaderTitle("Actions");
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
itemIndex = info.position;
}
public boolean onContextItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.call:
call();
Toast.makeText(getContext(), "Calling...", Toast.LENGTH_LONG).show();
return true;
case R.id.sms:
Toast.makeText(getContext(), "SMS", Toast.LENGTH_LONG).show();
return true;
case R.id.email:
Toast.makeText(getContext(), "Email", Toast.LENGTH_LONG).show();
return true;
case R.id.editContact:
Toast.makeText(getContext(), "Editing", Toast.LENGTH_LONG).show();
return true;
case R.id.deleteContact:
Toast.makeText(getContext(), "Deleting", Toast.LENGTH_LONG).show();
return true;
default:
return super.onContextItemSelected(item);
}
}
private void call() {
Log.d("PHONE", String.valueOf(itemIndex));
receivedData = (Person)dbAdapter.getPhone(itemIndex);
Log.d("PHONE",receivedData.getPhone().toString());
Intent call = new Intent(Intent.ACTION_CALL);
call.setData(Uri.parse("tel:" + receivedData.getPhone()));
startActivity(call);
}
ContextMenuRecyclerView:
public class ContextMenuRecyclerView extends RecyclerView {
private RecyclerContextMenuInfo mContextMenuInfo ;
public ContextMenuRecyclerView(Context context) {
super(context);
}
public ContextMenuRecyclerView(Context context, AttributeSet attrs)
{
super(context,attrs);
}
public ContextMenuRecyclerView(Context context, AttributeSet attrs, int defStyle)
{
super(context,attrs,defStyle);
}
//I think problem is somewhere in this function. I dont think its getting called.
@Override
protected ContextMenu.ContextMenuInfo getContextMenuInfo()
{
return mContextMenuInfo;
}
@Override
public boolean showContextMenuForChild(View originalView)
{
final int longPressPosition = getChildAdapterPosition(originalView);
if (longPressPosition >=0)
{
final long longPressId = MyContacts.recyclerView.getAdapter().getItemId(longPressPosition); //MyContacts.recyclerView.
mContextMenuInfo = new RecyclerContextMenuInfo(longPressPosition, longPressId);//createContextMenuInfo
return super.showContextMenuForChild(originalView);
}
return false;
}
public static class RecyclerContextMenuInfo implements ContextMenu.ContextMenuInfo
{
//position in adapter for which context menu is being displayed
final public int position;
//row id of the item for which context menu is being displayed
final public long id;
public RecyclerContextMenuInfo(int position, long id)
{
this.position = position;
this.id = id;
}
}
}
My RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>{
static Context c;
private LayoutInflater inflater;
List<Person> persons = Collections.emptyList();
public RecyclerViewAdapter(FragmentActivity context, List<Person> persons){
inflater = LayoutInflater.from(context);
this.persons = persons;
this.c = context;
}
//Initializing view holder
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.single_row, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Person current = persons.get(position);
holder.image.setImageResource(R.drawable.contact);
holder.name.setText(current.getName());
holder.phone.setText(current.getPhone());
holder.itemView.setLongClickable(true);
}
@Override
public int getItemCount() {
return persons.size();
}
@Override
public long getItemId(int position) {
return super.getItemId(position);
}
public static class MyViewHolder extends RecyclerView.ViewHolder
{
ImageView image;
TextView name;
TextView phone;
ItemClickListener itemClickListener;
ContextMenuRecyclerView recyclerView = new ContextMenuRecyclerView(c);
public MyViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.listImage);
name = (TextView) itemView.findViewById(R.id.listName);
phone = (TextView) itemView.findViewById(R.id.listPhone);
}
}
}
Please help me figure out!!