【问题标题】:Android: AlertDialog inside another AlertDialog's listenerAndroid:另一个AlertDialog的侦听器中的AlertDialog
【发布时间】:2012-09-21 17:14:30
【问题描述】:

更新:Eclipse 一定有问题,因为我在崩溃时没有记录任何错误。当应用程序按描述崩溃时,我没有收到此错误:

The specified child already has a parent. You must call removeView() on the child's 
parent first.

在第二次运行 noteview.show() 方法时会出现这种情况。


原帖

我有一个AlertDialog 的问题,它是从另一个AlertDialog 的侦听器内部启动的。

这是创建对话框和侦听器的代码以及对话框的show()

AlertDialog.Builder mdialog;
ArrayAdapter<String> popmenu;
EditText input;

mdialog = new AlertDialog.Builder(ShoppingListApp03Activity.this);
popmenu  = new ArrayAdapter<String>(ShoppingListApp03Activity.this,
           android.R.layout.select_dialog_item);
popmenu.add("Notes");
popmenu.add("Remove");
noteview = new AlertDialog.Builder(ShoppingListApp03Activity.this)
noteview.setTitle("Notes");
input = new EditText(this);
noteview.setView(input);

lv.setOnItemLongClickListener(new OnItemLongClickListener() {
   @Override
       public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
                                                     long id) {
           final String sitem = items.get(position).getId();
           mdialog.setAdapter(popmenu, new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int item) {
                 if (item == 0) {
                    updateFooter("Not implemented. (" + sitem + ")");
                noteview.show();
                 } else {
                    deleteitem = Integer.parseInt(sitem);
                    rmvdialog.show();
                 }
              }
           });

           mdialog.show();
           return false;
        }
     });

/* Click listener for the "Notes" popup menu: */
noteview.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
        Editable value = input.getText();
        // Do something with value!
    }
});
noteview.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
        // Canceled.
    }
});

onItemLongClickListener 会打开一个弹出菜单,其中有两个选项。

第二个,以rmvdialog() 开头,做得很好。没有问题。

第一个打开注释对话框有一个问题:第一次访问时,它打开注释对话框并显示消息以及OKCancel 按钮。但是,在返回列表(主视图)后,通过单击注释对话框中的OKCancel(因为两者都还没有执行任何操作),再次长按并选择注释对话框会使应用程序崩溃。

崩溃没有错误记录。 try-catch 周围的 noteview.show() 也不会透露任何信息。

我在看自己的代码时会失明,所以设计中可能有一些烂掉的东西,但我看不到是什么。

这里的整体功能是一个包含多个项目的列表。长按其中一项时,会显示一个包含两个条目的弹出菜单。然后,当长按名为“notes”的那个时,会出现一个对话框,用于显示/编辑列表中的项目的文本。

【问题讨论】:

  • 您永远不会关闭对话框,因此您的第二个节目可能会导致所描述的崩溃。您是否尝试过解耦(抱歉)凌乱的代码以使其更干净?
  • 关于如何做到这一点的任何提示(使其更清洁)?当使用像这样的内联类和侦听器时,我发现很难编写非常整洁的代码......我得到了不关闭对话框部分。但是我应该在哪里/如何解雇它?在监听器中?
  • 顺便说一句:我尝试通过在单击取消按钮时添加“dialog.cancel()”来取消侦听器中的对话框。这并没有改变任何东西 - 当我第二次打开对话框并单击取消时,应用程序仍然崩溃(或引发异常)。
  • 如果有异常,粘贴即可。 Cancel 不会从视图堆栈 afaik 中将其关闭。所以你真的应该调用dismiss而不是cancel。
  • noteview.cancel() 或 noteview.dismiss() 绝对什么都不做。我可以打开一次对话框,但是当我第二次尝试打开它时,异常被捕获:java.lang.IllegalStateException:指定的孩子已经有一个父母。您必须先在孩子的父母上调用 removeView()。

标签: android android-alertdialog


【解决方案1】:

正如你也刚刚发现我所做的一样。这是我向您要求的测试活动。如您所见,它是您的精简版(除了我使用 onclick 而不是 onlongclick)

public class MainActivity extends Activity {

    private Builder firstDialogBuilder;
    private AlertDialog firstDialog;
    private Builder secondDialogBuilder;
    private AlertDialog secondDialog;
    private ListView secondListView;
    private ListView firstListView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        firstDialogBuilder = new AlertDialog.Builder(this);
        firstListView = new ListView(this);
        firstListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[] {"First Item1", "First Item2"}));
        firstDialogBuilder.setView(firstListView);
        firstListView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                secondListView = new ListView(MainActivity.this);
                secondListView.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, new String[] {"Second Item1", "Second Item2"}));
                secondDialogBuilder.setView(secondListView);
                secondDialog = secondDialogBuilder.create();
                secondDialog.show();
            }
        });

        secondDialogBuilder = new AlertDialog.Builder(this);
        secondListView = new ListView(this);
        secondListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[] {"Second Item1", "Second Item2"}));
        secondDialogBuilder.setView(secondListView);

        secondDialogBuilder.setPositiveButton("ok", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), "ok on second", Toast.LENGTH_SHORT).show();
                secondDialog.dismiss();
            }
        });
        secondDialogBuilder.setNegativeButton("cancel", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), "cancel on second", Toast.LENGTH_SHORT).show();
                secondDialog.dismiss();
            }
        });

        firstDialog = firstDialogBuilder.create();
        firstDialog.show();
    }
}

下次,请提供类似的东西来帮助我们帮助你:)

【讨论】:

  • 非常感谢。是的,对不起 - 我只是坐在这里试图腾出时间重写没有所有其他对象和东西的活动。下次我会提前做。所以,总结一下:问题是我只创建了 AlertDialogBu​​ilder,而不是先创建 Builder,然后再创建 AlertDialog。而且,我还注意到我必须从 on(Long)Click 方法中的 Builder 创建 AlertDialog ,就像你在这里做的那样。如果我在现场创建它,则不会添加按钮和侦听器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多