如何根据在ListActivity中长按哪个项目来设置特定的上下文菜单?

5

我有一个列表活动,并选择手动添加第一个项目,即“添加新项目...”。

我已经在onCreate中直接使用registerForContextMenu(getListView())为整个listview注册上下文菜单。

当上下文菜单被构建时,系统会调用onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)。其中的View v是listview,我找不到一种方法来知道哪个项目被长按了。

我可以创建一个XML布局,其中包含“添加新项目...”的布局,然后在其后添加一个列表视图,由活动进行填充,并对上下文菜单作出反应,但我相信有一种方法可以在没有任何XML布局的情况下解决此问题。

我尝试使用registerForContextMenu注册列表视图中的每个视图,这可以工作,但是列表视图不再响应触摸。

以下是我的活动代码清单:

public class AMain extends ListActivity {
    private List<String> pregList;
    private List<Long> pregIds;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        pregList = new ArrayList<String>();
        pregIds = new ArrayList<Long>();

        registerForContextMenu(getListView());
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        // TODO: hide the menu for the 1st item!!
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.context_menu, menu);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        Logger.d("id = "+info.id);
        switch (item.getItemId()) {
        case R.id.menu_show:
            showPregnancy((int) info.id);
            return true;

        case R.id.menu_edit:
            editPregnancy((int) info.id);
            return true;

        case R.id.menu_delete:
            //TODO: do the deletion
            return true;

        default:
            return super.onContextItemSelected(item);
        }
    }

    protected void onStart() {
        super.onStart();

        clearPregList();
        loadPregList();
        getListView().setAdapter(new PregnancyListAdapter(this));
    }

    void clearPregList() {
        pregList.clear();
        pregIds.clear();
    }

    void loadPregList() {
        PregnanciesDbAdapter db = new PregnanciesDbAdapter(this);
        db.open();
        Cursor c = db.getPregnancies();

        if (c != null) {
            do {
                pregList.add(c.getString(c.getColumnIndex(PregnanciesDbAdapter.KEY_PREG_NOM)));
                pregIds.add(c.getLong(c.getColumnIndex(PregnanciesDbAdapter.KEY_PREG_ROWID)));
            } while (c.moveToNext());
            c.close();
        }

        db.close();
    }

    private class PregnancyListAdapter extends BaseAdapter {
        private Context context;

        public PregnancyListAdapter(Context ctx) {
            context = ctx;
        }

        @Override
        public int getCount() {
            return pregList.size()+1;
        }

        @Override
        public Object getItem(int position) {
            if (position == 0) { // add button
                return getString(R.string.addPreg);
            } else {
                return pregList.get(position-1);
            }
        }

        @Override
        public long getItemId(int position) {
            if (position == 0) {
                return -1;
            }
            return pregIds.get(position-1);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LinearLayout itemLayout;

            itemLayout= (LinearLayout) LayoutInflater.from(context).inflate(R.layout.homelist_item_pregnancy, parent, false);

            ImageView logo = (ImageView) itemLayout.findViewById(R.id.logo);
            TextView pregName = (TextView) itemLayout.findViewById(R.id.pregName);

            if (position == 0) {
                itemLayout.setFocusable(false);
                itemLayout.setFocusableInTouchMode(false);
                pregName.setText(getString(R.string.addPreg));
            } else {
                logo.setVisibility(View.INVISIBLE);
                pregName.setText(pregList.get(position-1));
            }

            itemLayout.setId(position);

            return itemLayout;
        }
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        if (position == 0) {
            startActivity(prepareIntent(AShowPregnancy.class, 0));
        } else {
            showPregnancy(position-1);
        }
    }

    void showPregnancy(int pregId) {
        startActivity(prepareIntent(AShowPregnancy.class, pregId));
    }

    void editPregnancy(int pregId) {
        startActivity(prepareIntent(ANewPregnancy.class, pregId));
    }

    Intent prepareIntent(Class<?> className, int pregId) {
        Intent i = new Intent(this, className);

        if (pregId > 0) {
            PregnanciesDbAdapter db = new PregnanciesDbAdapter(this);
            db.open();
            Pregnancy p = db.load(pregIds.get(pregId));
            db.close();
            i.putExtra(C.EXTRA_PREGNANCY, p);
        }

        return i;
    }
}

感谢阅读。希望您能提供帮助。
1个回答

4

天啊,又来了。我自己找到了如何做,而且比易懂还要简单。

AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
// info.position is the position in the ListView

我讨厌我自己 :)

天啊,非常感谢。我也遇到了同样的问题,一直在想menuInfo是干嘛用的,因为除了通常的对象方法之外,似乎没有其他公开可访问的内容。 - Leif Andersen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接