0

我正在使用FirebaseRecyclerView在我的應用程序的片段中顯示「圖表」(在應用程序中定義)的列表。可以長按列表中的項目以彈出包含選項的菜單。如何獲取RecyclerView中哪些項目被點擊以生成上下文菜單的詳細信息?

我遇到的困難是,當用戶點擊彈出菜單中的某個項目時,我無法獲取被點擊的項目的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

我的解決辦法有很多運動部件的,但整體的概念很簡單:用一個Intent來傳遞你想要的數據。您不能依賴ContextMenu.ContextMenuInfo menuInfo參數,因爲只有當您的上下文菜單連接到ListViewGridView時纔會出現此參數。

第一步,您需要將您最終想要的所有信息(這可能是位置,或者可能是更直接的東西)獲取到您的ViewHolder。您需要這個,因爲您可以撥打 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; 
} 
+0

完美,謝謝!我想通過ChartKey字符串,因此將其設置爲ViewHolder中的變量,然後將其填充到bindToPost中。我有點困惑的線menu.findItem(R.id.your_item_here),因爲我把實際列表項的ID,才意識到它是爲了菜單項,所以我只是把menu.findItem( 0)和menu.findItem(1),這些工作。再次,非常感謝,本,這真的幫了大忙! – Sharon

+0

'MyViewHolder holder =(MyViewHolder)recycler.getChildViewHolder(v);'不適合我,因爲'v'是'RecyclerView'本身,而不是它的子視圖。關於可能發生什麼的任何提示? – DanXPrado

+1

@DanXPrado OP爲每個'ViewHolder'的item視圖調用'registerForContextMenu()';你必須直接在你的'RecyclerView'上調用它。這本身並不「不好」,但這意味着_conceptually_用戶點擊recyclerview而不是一個項目,所以你不會有一個項目可以使用。 –

相關問題