2016-08-15 52 views
0

我正在RecyclerView上實施長按。當用戶長按RecyclerView時,它會顯示一個帶有刪除選項的菜單欄。現在我遇到了這種實現的兩個問題。如何在CustomAdapter中的Recycler視圖上實現LongPress?

首先,菜單欄不會覆蓋狀態欄。它彈出狀態欄上方。我所說的狀態欄是應用程序名稱所在的欄。我如何使它與狀態欄重疊?

其次,我改變了最初編寫代碼的方式,現在我正在爲不同的java文件實現回收器視圖的適配器。我將活動的上下文從片段傳遞到此適配器,但是當我長按時它顯示此錯誤。

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.MenuInflater android.support.v4.app.FragmentActivity.getMenuInflater()' on a null object reference 
at onCreateActionMode 

這是我實現我的片段:

public ModalMultiSelectorCallback mDeleteMode = new ModalMultiSelectorCallback(mMultiSelector) { 

     @Override 
     public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { 
      super.onCreateActionMode(actionMode, menu); 
      getActivity().getMenuInflater().inflate(R.menu.list_item_delete, menu); 
      return true; 
     } 

在onCreateView在這個片段我這樣做:

context = getActivity(); 

而且我發送到我的適配器用我的ArrayList:

customAdapter = new MyCustomAdapter(context, myArrayList); 

在我的自定義適配器我這樣做:

public MyCustomAdapter(Context context, ArrayList<myArrayList> myArrayList) { 
     mContext = context; 
     this.myArrayList= myArrayList; 
    } 

,並在這個適配器,我有一個名爲CustomRecyclerViewHolder一個內部類,我實現我的onLongPress

@Override 
     public boolean onLongClick(View v) { 

      ((AppCompatActivity) mContext).startSupportActionMode(myFragment.mDeleteMode); 
      myFragment.mMultiSelector.setSelected(this, true); 
      return true; 
     } 

這NullPointerException異常如上結束。任何想法爲什麼?

+0

你在哪裏創建'mDeleteMode'? – Bryan

+0

在我的片段類 –

回答

0

我的猜測是您正在使用Big Nerd Ranch的recyclerview-multiselect庫和this sample code作爲您項目的基礎。在此示例項目中,ModalMultiSelectorCallback對象正在全局範圍內實例化。

這看起來像實例化這個目標的最好的地方不考慮你正在嘗試調用getActivity(),它可以是null直到片段的onCreate()方法被調用。我會按照這些步驟來解決這個問題。

首先,使用actionMode.getMenuInflater()代替getActivity(),因爲ActionMode將提供Context。接下來,創建您的實現擴展ModalMultiSelectorCallback類:

public class CustomMultiSelectorCallback extends ModalMultiSelectorCallback { 

    public CustomMultiSelectorCallback(MultiSelector multiSelector) { 
     super(multiSelector); 
    } 

    @Override 
    public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { 
     super.onCreateActionMode(actionMode, menu); 
     actionMode.getMenuInflater().inflate(R.menu.crime_list_item_context, menu); 
     return true; 
    } 

    @Override 
    public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { 
     ... 
    } 
} 

最後,在你的FragmentonCreate()方法創建ModalMultiSelectorCallback實例:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mMultiSelector = new MultiSelector(); 
    mDeleteMode = new CustomMultiSelectorCallback(mMultiSelector); 
} 
+0

我將修補程序應用於我的代碼。但我最終得到一個空指針異常這裏 '公共CustomRecyclerViewHolder(查看ItemView控件){ 超(ItemView控件,myPrescriptionFragment.mMultiSelector);' 的錯誤是:'顯示java.lang.NullPointerException:試圖調用虛擬方法void com.bignerdranch.android.multiselector.MultiSelector.bindHolder(com.bignerdranch.android.multiselector.SelectableHolder,int,long)'在一個空對象引用上' –

+0

@KamilKamili至少它看起來好像讓它進一步沿着'片段'生命週期。現在看起來你的'ViewHolder'中的'mMultiSelector'是'null'。這隻有在'onCreate()'後'mMultiSelector'爲'null'時纔會發生,因爲'Adapter'應該在'onCreateView()'中設置。你確定你在'onCreate()'中實例化了'mMultiSelector'嗎? – Bryan

+0

是的,我做到了,就像你是怎麼說的 –

0

你是過於複雜的實現。它不應該在適配器內部進行所有的自定義處理,而應該在保存它的活動/片段內部,適配器應限於處理列表本身。這樣做的正確方法是在適配器中創建點擊監聽器,並且可以在您創建RecyclerView的同一位置處理回調。

在適配器中,創建一個接口:

public interface ClickListener { 
    void onItemClick(View v, int position); 
    void onLongItemClick(View v, int position); 
} 

然後在onCreateViewHolder創建你所需要的聽衆:

@Override 
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_item, parent, false); 

    final ViewHolder viewHolder = new ViewHolder(v); 
    v.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      listener.onItemClick(v, viewHolder.getAdapterPosition()); 
     } 
    }); 
    v.setOnLongClickListener(new View.OnLongClickListener() { 
     @Override 
     public boolean onLongClick(View v) { 
      listener.onLongItemClick(v, viewHolder.getAdapterPosition()); 
      return true; 
     } 
    }); 
    return viewHolder; 
} 

您將需要創建界面,當你創建你的適配器,所以處理在您的構造函數中:

public MyAdapter(List<MyObject> list, ClickListener listener) { 
    this.list = list; 
    this.listener = listener; 
} 

而當您創建適配器:

mAdapter = new MyAdapter(list, new ColorAdapter.ClickListener() { 
     @Override 
     public void onItemClick(View v, int position) { 
      //click logic 
     } 

     @Override 
     public void onLongItemClick(View v, final int position) { 
      //long press logic 
     } 
    }); 

理想的情況下,一旦你實現這個你就沒有必要通過上下文到您的適配器,以及額外的邏輯和null檢查可以處理,他們應該是,該適配器可用於其他實現重複使用。

相關問題