在Recycler View上创建上下文菜单时,menuInfo为空

3
我试图在Recycler View的项上单击时显示上下文菜单,并选择调用已点击名称的个人。但是,由于在onCreateContextMenu()中的contextMenuInfo中得到null,所以我无法检索电话号码。虽然我已经参考了许多答案并相应地编写了代码,但仍然无法正确解决它。 以下是我的代码:
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>

我的碎片包含了可回收视图:

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);
}

上下文菜单RecyclerView:

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;
    }
  }
} 

我的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);


    }


}

请帮我解决这个问题!!

1个回答

1
我是这样做的,声明了一个私有的MyViewHolder holder字段,而不仅仅是将其作为局部变量在onCreateContextMenu内部调用它。
getItem(vh.getAdapterPosition()); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接