onCreateContextMenu在滚动列表中的实现

《android权威编程指南》的学习

在实现本书中criminalintent应用时,想用onCreateContextMenu长按菜单来实现记录的删除、添加等功能


1.onCreateContextMenu的创建

我实现的是长按每条记录的整体视图弹出菜单(即这个视图中的任意位置),而不是视图中的某个控件。首先建立监听器。
代码1-1:

  public CrimeHolder(View itemView){
            super(itemView);
            itemView.setOnClickListener(this);
            itemView.setOnCreateContextMenuListener(new
        View.OnCreateContextMenuListener() {
                @Override
                public void onCreateContextMenu(ContextMenu contextMenu, View v, ContextMenu.ContextMenuInfo contextMenuInfo) {
                    contextMenu.setHeaderTitle("选择操作");
                    contextMenu.add(0,0,0,R.string.crime_delete);
                    //或者contextMenu.add(0,0,0,"删除");
                    contextMenu.add(0,1,0,"添加");
                  mId=mCrime.getId();
                }
          });

2.为每个事件添加处理过程

通过覆盖onContextItemSelected(MenuItem item)方法来实现,关于添加事件书中有详细的代码及讲解(p223),这里我们主要说明一下删除。先看一下代码1-2:

@Override
    public boolean onContextItemSelected(MenuItem item){
 switch (item.getItemId()){
           //添加事件的处理
            case 1:
                Crime crime=new Crime();
                CrimeLab.get(getActivity()).addCrime(crime);
                Intent intent=CrimePagerActivity
                        .newIntent(getActivity(),crime.getId());
                startActivity(intent);
                return true;
            //删除事件的处理
            case 0:
               mChanged= CrimeLab.get(getActivity()).getPosition(mId);
                CrimeLab.get(getActivity()).deleteCrime(mChanged);
                updateUI();
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }

mchanged是我在CrimeListFragment中定义的一个int私有变量:

private int mChanged;

此变量用来实现从CrimeFragment中得到被改变过时间与日期等信息的fragment的编号,然后在CrimeListFragment中刷新,之前本书中要求我们用

mAdapter.notifyItemChanged(mChanged);来实现刷新被改变的具体条目而不是用

mAdapter.notifyDataSetchanged();全部刷新。其实任意的int型变量都可以用来作为我们要删除的条目的编号,之所以在这里用到mChanged,是因为我们删除掉之后必须更新一下我们的视图才能显示出效果(见代码1-2中删除事件的updateUI()方法),而在updateUI中:

private void updateUI(){
CrimeLab crimeLab=CrimeLab.get(getActivity());
List<Crime> crimes=crimeLab.getCrimes();
if(mAdapter==null) {
mAdapter = new CrimeAdapter(crimes);
mCrimeRecyclerView.setAdapter(mAdapter);
}else{
mAdapter.notifyItemChanged(mChanged);
}
updateSubtitle();
}

如果只是长按菜单,就没有实现CrimeListFragement与CrimeFragment的通信,故mChanged就没有实际的值,app会报错。

好了,那么现在如何得到我们长按的那个条目的编号呢?
见代码1-1中: mId=mCrime.getId();mId是定义的一个UUID变量。
在crimeLab中我增加了两个方法:

//得到当前id对应的crime在列表中的编号
public int getPosition(UUID id){
for(Crime crime:mCrimes){
if(crime.getId().equals(id)){
return mCrimes.indexOf(crime);
}
}
return 0;
}

//列表的对应编号的crime的删除
public void deleteCrime(int position){mCrimes.remove(position);}

点击运行,即可看见效果。

3.关于建立菜单的知识整合

  • 1

    注意:onContextItemSelected的实现方法是onContextItemSelected,它只能在Activity中响应!!

即:一定要是一个Activity去实现这个ListView,假如是其他的组件比如Dialog,Dialog.setContentView(ListView) 然后再去设置它的onContextItemSelected就无法被响应。

  • 2
    onCreateOptionsMenu :此方法为创建菜单方法,这个菜单就是你在点击手机menu键时会看到的菜单。
    onCreateContextMenu :此方法为创建菜单方法,你还需要对此菜单进行注册Activity.registerForContextMenu(View view),这个菜单是在你长按前面注册的view时看到的菜单。
    onMenuItemSelected :当你选择上面两种菜单任意一种时都会触发这个事件。
    onOptionsItemSelected :这个方法只在onCreateOptionsMenu 创建的菜单被选中时才会被触发。
    onContextItemSelected :这个方法只在onCreateContextMenu 创建的菜单被选中时才会被触发。

注:关于 onMenuItemSelected 与 onContextItemSelected的区别(此问题我暂时没遇到):
查阅于别人的博客,大致意思为:当同时使用这两个方法时,由于优先级的问题,onMenuItemSelected会先被调用,如果我们需要的菜单不在其中是就会返回false,并且没有执行onContextItemSelected.解决方法为:在onMenuItemSelected中添加语句当在某个特定的条件时,就调用onContextItemSelected.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值