我正在对RecyclerView实施长按。当用户长按CyclelerView时,它会显示一个带有删除选项的菜单栏。现在我遇到了这种实现的两个问题。
首先,菜单栏不会覆盖状态栏。它弹出状态栏上方。我说的状态栏是应用程序名称所在的栏。如何使其与状态栏重叠?
其次,所以我改变了我最初编写代码的方式,现在我正在为不同的java文件中的recycler视图实现适配器。我将活动的上下文从片段传递给此适配器,但是当我长按它时会显示此错误。
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;
}
在这个Adapter中,我有一个名为CustomRecyclerViewHolder的内部类,我实现了我的onLongPress
@Override
public boolean onLongClick(View v) {
((AppCompatActivity) mContext).startSupportActionMode(myFragment.mDeleteMode);
myFragment.mMultiSelector.setSelected(this, true);
return true;
}
如上所述,最终会出现NullPointerException。有什么想法吗?
答案 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) {
...
}
}
最后,在ModalMultiSelectorCallback
的{{1}}方法中创建onCreate()
的实例:
Fragment
答案 1 :(得分:0)
您的实施过于复杂。而不是在适配器内进行所有自定义处理,它应该在持有它的activity / fragment中,适配器应限于处理列表本身。执行此操作的正确方法是在适配器中创建单击侦听器,并在您创建RecyclerView的相同位置处理回调。
在适配器中,创建一个界面:
model
然后在onCreateViewHolder中创建所需的侦听器:
public interface ClickListener {
void onItemClick(View v, int position);
void onLongItemClick(View v, int position);
}
创建适配器时需要创建接口,因此请在构造函数中处理:
@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;
}
理想情况下,一旦实现了这一点,就不需要将Context传递给适配器,并且可以在应有的位置处理其他逻辑和空值检查,适配器可以重用于其他实现。