OnContextItemSelected не запускается, когда он вызывается из окна диалога

Dialog dialog;

private void opendialog() {
    dialog = new Dialog(MainActivity.this);
    dialog.setContentView(R.layout.popup);
    dialog.setTitle(R.string.msettings);
    RelativeLayout reply_layout = (RelativeLayout) dialog
            .findViewById(R.id.reply_layout);
    final RelativeLayout ringtone_layout = (RelativeLayout) dialog
            .findViewById(R.id.ringtone_layout);
    registerForContextMenu(ringtone_layout);

    ringtone_layout.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            openContextMenu(ringtone_layout);
        }
    });
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderTitle("Select The Action");
    menu.add(0, v.getId(), 0, "Edit");
    menu.add(0, v.getId(), 1, "Delete");
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    System.out.println("Inside onContextItemSelected");
    return super.onContextItemSelected(item);
}

onContextItemSelected никогда не вызывается при использовании контекстного меню внутри диалогового окна. Что-то не так с моим кодом? Спасибо заранее.

Ответы

Ответ 1

ПРИМЕЧАНИЕ.. Поскольку этот ответ, кажется, получает некоторое внимание (upvotes), я редактирую фрагмент кода, чтобы отобразить более краткий ответ на вопрос.

Вы пытаетесь зарегистрироваться для контекстного меню для элемента вида в диалоговом окне, но из действия. Этот подход неверен. Вам действительно нужно подклассы Dialog, а затем создавайте и расширяйте свои взгляды, а затем переопределяйте onCreateContextMenu() там, чтобы выполнить свою работу и зарегистрировать свое представление для контекстного меню. Затем вы должны создать экземпляр этого диалога. Итак, это будет что-то вроде:

public class Mydialog extends Dialog {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.popup);
        dialog.setTitle(R.string.msettings);
        RelativeLayout reply_layout = (RelativeLayout) findViewById(R.id.reply_layout);
        final RelativeLayout ringtone_layout = (RelativeLayout) findViewById(R.id.ringtone_layout);
        registerForContextMenu(ringtone_layout);
        ringtone_layout.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                openContextMenu(ringtone_layout);
            }
        });
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle("Select The Action");
        menu.add(0, v.getId(), 0, "Edit");
        menu.add(0, v.getId(), 1, "Delete");
    }

    // You should do the processing for the selected context item here. The
    // selected context item gets passed in the MenuItem parameter in 
    // the following method. In my answer I am force calling the onContextItemSelected()
    // method but you are free to do the actual processing here itself
    @Override 
    public boolean onMenuItemSelected(int aFeatureId, MenuItem aMenuItem) {
        if (aFeatureId==Window.FEATURE_CONTEXT_MENU)
            return onContextItemSelected(aMenuItem);
        else 
            return super.onMenuItemSelected(aFeatureId, aMenuItem);
    } 

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        // Avoid using System.out.println() - instead use Android Logging
        return super.onContextItemSelected(item);
    }
}

Теперь вы можете создать экземпляр этого диалога, и ваши представления будут иметь успешно зарегистрированный элемент контекста. Итак, ваш openDialogMethod() теперь будет выглядеть так:

private void opendialog() {
    dialog = new MyDialog(MainActivity.this);
    // the context menu will now be registered
    dialog.show();
}

Хотя вы первоначально передавали контекст активности в созданный вами Диалог, вы не можете передавать слушателям контекстного меню, как это. Для этого вам придется подклассифицировать ваше диалоговое окно, как показано выше.

РЕДАКТИРОВАТЬ:. Посмотрев на ответ Zsolt, я узнал, что я пропустил эту строку кода, которой у вас не было. Вам необходимо:

ringtone_layout.setOnCreateContextMenuListener(this);

То, что вы говорите о насильственном вызове контекстного меню, на самом деле верно. Вы просто вызываете обычное меню, а затем передаете этот идентификатор на обратный вызов контекстного меню. Предложение if передается, потому что идентификатор находится из контекстного меню.

И после некоторого дальнейшего чтения, похоже, что вы должны выполнять управление вашим меню на onMenuItemSelected(), а не в onContextItemSelected(). Итак, то, что у вас сейчас, является правильным, и вам не нужно принудительно называть другой метод. Просто выполните свою обработку в onMenuItemSelected().

Ответ 3

public class MusicsetDialog extends Dialog implements OnClickListener {
    private RelativeLayout ringtone_layout;

    public MusicsetDialog(Context context) {
        super(context);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.music_popup);
        setTitle(R.string.msettings);

        ringtone_layout = (RelativeLayout) findViewById(R.id.ringtone_layout);

        ringtone_layout.setOnClickListener(MusicsetDialog.this);

        registerForContextMenu(ringtone_layout);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.ringtone_layout:
            openContextMenu(ringtone_layout);
            break;          
        default:
            break;
        }
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        menu.setHeaderTitle("Select The Action");
        // groupId, itemId, order,title
        menu.add(0, v.getId(), 0, "Edit");
        menu.add(0, v.getId(), 1, "Delete");
        super.onCreateContextMenu(menu, v, menuInfo);
    }

    @Override 
    public boolean onMenuItemSelected(int aFeatureId, MenuItem aMenuItem) {
        if (aFeatureId==Window.FEATURE_CONTEXT_MENU)
            return onContextItemSelected(aMenuItem);
        else 
            return super.onMenuItemSelected(aFeatureId, aMenuItem);
    } 

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        // System.out.println("onContextItemSelected");
        Log.d("MusicsetDialog", "onContextItemSelected");
        return super.onContextItemSelected(item);
    }
}

Я создал подкласс для mydialog и расширенный диалог и выполнил процедуру Sunil. Но все же onContextItemSelected не вызывалось. поэтому после выполнения некоторых исследований я Override onMenuItemSelected и передал выбранный MenuItem на onContextItemSelected, и он работал нормально. Возможно, я вызываю onContextItemSelected. Я не знаю. Я новичок в android, любое объяснение, почему onContextItemSelected по-прежнему не называется автоматически, будет оценено.. Спасибо..

Ответ 4

Попробуйте это

new AlertDialog.Builder(this) 
        .setSingleChoiceItems(items, 0, null) 
        .setPositiveButton(R.string.ok_button_label, new DialogInterface.OnClickListener() { 
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
                int selectedPosition = ((AlertDialog)dialog).getListView().getCheckedItemPosition();
                // Do something useful withe the position of the selected radio button 
            } 
        }) 
        .show();