如何获取单击RecyclerView中的哪个项目以生成上下文菜单的详细信息?

时间:2017-09-19 17:14:26

标签: android firebase-realtime-database android-recyclerview recycler-adapter

我正在使用FirebaseRecyclerView来显示'图表' (在应用中定义)在我的应用中的片段中。可以长按列表中的项目以弹出带有选项的菜单。

我遇到的困难是,当用户点击弹出菜单中的某个项目时,我无法获得所点击项目的ID。我已经在下面列出了ChartListFragment的相关部分,并标明了我遇到问题的地方。

public abstract class ChartListFragment extends Fragment {

    private FirebaseRecyclerAdapter<Chart, ChartViewHolder> mAdapter;
    private RecyclerView mRecycler;

    public ChartListFragment() {}

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        View rootView = inflater.inflate(
                R.layout.fragment_charts_list, container, false);

        mRecycler = (RecyclerView) rootView.findViewById(R.id.charts_list);
        mRecycler.setHasFixedSize(true);

        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        LinearLayoutManager mManager = new LinearLayoutManager(getActivity());
        mManager.setReverseLayout(true);
        mManager.setStackFromEnd(true);
        mRecycler.setLayoutManager(mManager);

        DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
        Query chartsQuery = getQuery(mDatabase);
        mAdapter = new FirebaseRecyclerAdapter<Chart, ChartViewHolder>(Chart.class, R.layout.item_chart,
                ChartViewHolder.class, chartsQuery) {

            @Override
            protected void populateViewHolder(final ChartViewHolder viewHolder, final Chart model, final int position) {
                final DatabaseReference chartRef = getRef(position);
                final String chartKey = chartRef.getKey();

                registerForContextMenu(viewHolder.itemView);

                viewHolder.bindToPost(model);
            }
        };

        mRecycler.setAdapter(mAdapter);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        if (v.getId()==R.id.chart_item) {
            MenuInflater inflater = getActivity().getMenuInflater();
            inflater.inflate(R.menu.menu_long_press_chart_name, menu);
        }
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

    // AT THIS POINT I THINK I SHOULD BE ABLE TO GET THE POSITION OF THE ITEM
    // THAT WAS CLICKED BY DOING SOMETHING LIKE
    //      int chartPos = info.position;
    //      Chart chartClicked = mAdapter.getItem(chartPos);
    // BUT info IS NULL, SO info.position CAUSES A CRASH
        switch(item.getItemId()) {
            case R.id.edit:
                // Show Edit Activity
                return true;
            case R.id.delete:
                // Show confirmation message
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }

}

1 个答案:

答案 0 :(得分:2)

我的解决方案有许多移动部件,但整体而言,概念非常简单:使用Intent传递所需的数据。您不能依赖ContextMenu.ContextMenuInfo menuInfo参数,因为仅当您的上下文菜单附加到ListViewGridView时才会显示此参数。

第一步是你需要在ViewHolder中获得你最终想要的所有信息(这可能是位置,也可能是更直接的信息)。您需要这样做,因为您可以在RecyclerView.getChildViewHolder()中致电onCreateContextMenu,以便访问与您点击的任何项目相关联的数据。

下一步是使用Intent将此数据附加到上下文菜单。在onCreateContextMenu()实施中,在菜单膨胀后,您可以写下这样的内容:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    ...
    MyViewHolder holder = (MyViewHolder) recycler.getChildViewHolder(v);
    int position = holder.position; // or any custom data you want, set up in onBindViewHolder()

    Intent data = new Intent();
    data.putExtra("position", holder.position);
    menu.findItem(R.id.your_item_here).setIntent(data);
    menu.findItem(R.id.your_other_item_here).setIntent(data);
}

最后,在您的onContextItemSelected()实施中,您可以访问此Intent并从中获取数据:

@Override
public boolean onContextItemSelected(MenuItem item) {
    int position = item.getIntent().getIntExtra("position", -1);
    // do something with position
    return true;
}