【问题标题】:Accessing a ListView item's text from Contextual Action Bar从上下文操作栏中访问 ListView 项的文本
【发布时间】:2012-05-04 15:04:28
【问题描述】:

我需要通过长按选择来访问 ListView 项中的文本。对于旧的 Android 版本,我已经使用下面的代码使用上下文菜单成功地完成了这项工作。

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

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.context_menu, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    String text = ((TextView) info.targetView).getText().toString();

    switch (item.getItemId()) {
        case R.id.getText:
            getText(text);
            return true;
        default:
            return super.onContextItemSelected(item);
    }
}

但是,对于较新的 Android 版本,我想使用上下文操作栏执行此操作,但在选择栏中的项目后无法弄清楚如何提取所选文本。下面的代码不起作用。

    myListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    myListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        String text = ((TextView) info.targetView).getText().toString();

            switch (item.getItemId()) {
                case R.id.contextDelete:
                    getText(text);
                    return true;;
                default:
                    return false;
            }
        }

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.context_menu, menu);
            return true;
        }

        //Other actionmode methods...
    });

上下文操作栏显示正常,但是当从中选择一个项目时,我在 AdapterContextMenuInfo 行收到 NullPointerException,因为这显然是为上下文菜单而不是操作栏制作的。也许对于动作栏有一些等价物吗?或者在这种情况下如何获取 ListView 项目文本?谢谢。

【问题讨论】:

    标签: android android-listview android-menu android-actionbar


    【解决方案1】:

    getCheckedItemPositions() on ListView 将返回用户检查过的项目位置,如果您使用CursorAdapter 之类的内容,getCheckedItemIds() 将返回其 ID 值。

    Here is a sample project 演示了在 API 级别 11+ 上使用 CHOICE_MODE_MULTIPLE_MODAL 并在旧设备上回退到上下文菜单。

    【讨论】:

    • 谢谢,示例项目帮助了我!但是,一个单独的问题是,如何使已选择的项目可见?对我来说,即使选择后,所有项目看起来都一样。
    • @mattboy:“不过是一个单独的问题,我如何才能看到已选择的项目?” -- 在行布局中做一些事情。在示例项目中,右侧有复选标记,您可以选中和取消选中行以确定操作模式应该影响什么。对于 Gmail,他们使用左侧的复选框。
    • 如何从每个 ListView 项中的 TextView 获取文本?
    【解决方案2】:

    我尝试在ListView 对象上使用getCheckedItemIds() 方法,但它什么也没返回(我没有使用Cursor 对象)。事实证明,这是人们一直面临的普遍问题。所以我想出了一个解决方法。在我的情况下,我必须使用项目 ID 来创建通知(只是尝试一些示例代码),所以这就是我获取它们的方法:

    我创建了一个ArrayList 来存储所有已选择项目的 ID。每次检查项目时,都会调用onItemCheckedStateChanged(..) 方法。我们可以使用这种方法根据状态变化更新ID的ArrayList。然后,当用户选择一个选项并调用onActionItemClicked() 方法时,我们可以使用存储在此列表中的 ID。代码如下:

    lv.setMultiChoiceModeListener(new MultiChoiceModeListener() {
                private ArrayList<Long> checkedIds = new ArrayList<Long>();
    
                        //Code omitted for brevity
    
                @Override
                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                    menu.add(0, 1, 0, R.string.context_create_notification);
                    return true;
                }
    
                @Override
                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                    switch(item.getItemId()){
                    case 1:
                        for(long id : checkedIds){
                            createNotification(id+1);
                        }
                        mode.finish();
                        break;
                    }
                    return true;
                }
    
                @Override
                public void onItemCheckedStateChanged(ActionMode mode, int position,
                        long id, boolean checked) {
    
                    if(checked){
                        checkedIds.add(id);
                    } else{
                        Iterator<Long> iter = checkedIds.iterator();
                        while(iter.hasNext()){
                            long stored = (Long) iter.next();
                            if(stored == id){
                                iter.remove();
                            }
                        }
                    }
                }
            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      • 1970-01-01
      相关资源
      最近更新 更多