【问题标题】:Android: Reuse AlertBuilder instanceAndroid:重用 AlertBuilder 实例
【发布时间】:2019-07-08 04:58:36
【问题描述】:

我已经创建了一个方法,并且在使用此对话框之前我只调用了一次该方法:

 private void makeAlertDialogBuilder() {
        binding = DataBindingUtil.inflate(LayoutInflater.from(getContext()),
                R.layout.revisited_dialog, null, false);
        alertBuilder = new AlertDialog.Builder(getContext()).setView(binding.getRoot())
                .setView(binding.getRoot());
        binding.btnCancel.setOnClickListener(v -> alertDialog.dismiss());
    }

我在工具栏中有一个菜单,所以我想点击添加菜单项,此对话框打开并显示新消息,当我单击编辑菜单项时显示带有新消息的对话框:

toolbar.setOnMenuItemClickListener(item -> {
    int id = item.getItemId();
    if (id == R.id.add_row) {
        alertDialog = alertBuilder
                .setMessage("Add")
                .setCancelable(false)
                .show();

        exGridAdapter = new RevisitGridAdapter(gridAdapter, baseClass, Action.ADD);
        initRecyclerView(exGridAdapter);
        return true;

    } else if (id == R.id.edit_row) {
        if (selectedItem != null) {
            alertDialog = alertBuilder
                    .setMessage("Edit")
                    .setCancelable(false)
                    .show();
            exGridAdapter = new RevisitGridAdapter(gridAdapter, baseClass, Action.EDIT, selectedItem);
            initRecyclerView(exGridAdapter);
        } 

第一次点击时,会显示对话框,但是当它被关闭并再次点击时,我得到了 ANR 错误:

指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。

我从alertBuilder 创建了一个对象,我想使用它吗?有可能还是我必须重新创建新的 alertBuilder 对象?

【问题讨论】:

  • 我认为这个错误来自RecyclerView
  • 我想这会对你有所帮助link
  • 当我在编辑菜单项@AbhayKoradiya 上单击两次时,我在此部分出现错误alertDialog = alertBuilder.setMessage("Edit")
  • 你需要先解散。检查我的答案。

标签: android android-alertdialog


【解决方案1】:

你可以在一个单独的类中使用这样的东西,例如我使用了 AlertUtils.java:

 public class AlertUtils
{
   public static void showOKDialog(Context context, String title, String message)
    {
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton(android.R.string.ok, null);
    builder.show();
    }
}

在这个方法中,你传递的Context可以是你Activity的this,例如:MyActivity.this或者一个fragment的getContext()

AlertUtils.showOKDialog(MyActivity.this, "对话框标题", "对话框中显示的消息");

【讨论】:

    【解决方案2】:
    AlertDialog.Builder alertDialog;  // Your Global Object
    
        AlertDialog.Builder getAlertDialogObject() {
            if (alertDialog != null) {
                return alertDialog;
            } else {
                alertDialog = new AlertDialog.Builder(LoginIssueScreen.this);
            }
            return alertDialog;
        }
    

    您需要为 AlertDialog 创建一个通用方法:-

        public void showAlerDialogResult(String msg, String title) {
    
                AlertDialog.Builder alertDialog = getAlertDialogObject();
                alertDialog.setMessage(msg);
                alertDialog.setIcon(R.drawable.ic_check_green);
                alertDialog.setTitle(title);
                alertDialog.setCancelable(false);
                alertDialog.setPositiveButton("OK", (dialogInterface, i) -> {
                    // Your code on click on ok
    
                });
                alertDialog.setNegativeButton("Cancel", (dialogInterface, i) -> {
                 // Your code on click on Cancel
    
            });
                alertDialog.show();
    
            }
    

    并像下面这样称呼它-:

    showAlerDialogResult("Add Button clicked", "Click Event");
    
                    or
    
    showAlerDialogResult("Edit Button clicked", "Click Event");
    

    【讨论】:

    • 我不希望每次都重新创建 AlertDialog.Builder。
    【解决方案3】:

    这个问题是由于再次打开同一个对话框而没有关闭上一个。

    您需要检查第一个对话框是否打开然后关闭它。喜欢,

    toolbar.setOnMenuItemClickListener(item -> {
        int id = item.getItemId();
        if (id == R.id.add_row) {
            if (alertDialog != null && alertDialog.isShowing()) {
                alertDialog.dismiss();
            }
            alertDialog = alertBuilder
                    .setMessage("Add")
                    .setCancelable(false)
                    .show();
    
            exGridAdapter = new RevisitGridAdapter(gridAdapter, baseClass, Action.ADD);
            initRecyclerView(exGridAdapter);
            return true;
    
        } else if (id == R.id.edit_row) {
            if (selectedItem != null) {
                if (alertDialog != null && alertDialog.isShowing()) {
                    alertDialog.dismiss();
                }
                alertDialog = alertBuilder
                        .setMessage("Edit")
                        .setCancelable(false)
                        .show();
                exGridAdapter = new RevisitGridAdapter(gridAdapter, baseClass, Action.EDIT, selectedItem);
                initRecyclerView(exGridAdapter);
            } 
    

    【讨论】:

    • 我再次遇到同样的错误 ` alertDialog = alertBuilder .setMessage("ٍEdit") .setCancelable(false) .show();` @AbhayKoradiya
    • 我在@AbhayKoradiya 之前以makeAlertDialogBuilder() 方法关闭了对话框
    【解决方案4】:

    我终于解决了我的问题,方法是从父级删除视图并以这种方法再次附加到它:

    public void showAlerDialogResult(String title) {
    
        ViewGroup parent = (ViewGroup) binding.getRoot().getParent();
        if (parent != null) {
            parent.removeView(binding.getRoot());
        }
        try {
            makeAlertDialogBuilder();
        } catch (InflateException e) {
            Logger.log(e.getMessage());
        }
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getContext())
                .setView(binding.getRoot());
        alertDialog = alertBuilder
                .setTitle(title)
                .setCancelable(false)
                .show();
    }
    

    我在我的问题中提到了makeAlertDialogBuilder(); 方法。 我希望它可以有所帮助。谢谢大家帮助我

    坦克给ChandraShekhar Kaushik

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      • 2019-06-18
      • 1970-01-01
      相关资源
      最近更新 更多