java - 如何在内部类初始化时访问自己的变量?

标签 java android

我有一个“DialogHelper”类,其中在各种上下文中使用了一堆静态方法,以使对话框的使用更加容易。其中一种方法是“三选对话框”,用户可以从三个按钮中进行选择以继续:

    public static AlertDialog createThreeChoiceDialog(final MyActivity activity, String title, String firstChoiceText,
            String secondChoiceText, String thirdChoiceText, View.OnClickListener firstChoiceListener, View.OnClickListener secondChoiceListener,
            View.OnClickListener thirdChoiceListener) {
        final View dView = activity.getLayoutInflater().inflate(R.layout.three_choice_dialog, null);
        final TextView explanatoryTV = (TextView) dView.findViewById(R.id.explanatoryTV);
        final TextView firstChoiceTV = (TextView) dView.findViewById(R.id.firstChoiceTV);
        final TextView secondChoiceTV = (TextView) dView.findViewById(R.id.secondChoiceTV);
        final TextView thirdChoiceTV = (TextView) dView.findViewById(R.id.thirdChoiceTV);

        explanatoryTV.setText(title);
        firstChoiceTV.setText(firstChoiceText);
        secondChoiceTV.setText(secondChoiceText);
        thirdChoiceTV.setText(thirdChoiceText);

        firstChoiceTV.setOnClickListener(firstChoiceListener);
        secondChoiceTV.setOnClickListener(secondChoiceListener);
        thirdChoiceTV.setOnClickListener(thirdChoiceListener);

        AlertDialog = etc...
        return alertDialog;
    }

我这样调用它:

    private void doSomething() {
        final AlertDialog alert = DialogHelper.createThreeChoiceDialog(activity, "title", "choice1", "choice2", "choice3",
                new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //do something 1

                alert.dismiss();
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //do something 2

                alert.dismiss();
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //do something 3

                alert.dismiss();
            }
        });

        alert.show();
    }

但是,“alert.show()”方法会出现错误:

variable 'alert' might not have been initialized yet

我的问题是,处理这种情况的最佳方法是什么?我想在用户选择一个选项时关闭该对话框。

这是我当前的解决方法:

    private void doSomething() {
        final ArrayList<AlertDialog> alerts = new ArrayList<>(); //<-- added ArrayList of AlertDialogs

        final AlertDialog alert = DialogHelper.createThreeChoiceDialog(activity, "title", "choice1", "choice2", "choice3",
                new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //do something 1

                alerts.get(0).dismiss(); //<-- accessed via ArrayList
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //do something 2

                alerts.get(0).dismiss(); //<-- accessed via ArrayList
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //do something 3

                alerts.get(0).dismiss(); //<-- accessed via ArrayList
            }
        });

        alerts.add(alert); //<-- add alert to ArrayList
        alert.show();
    }

它确实有效,但这不可能是最佳实践。我已经遇到过这个问题几次了,所以我最终决定询问处理这个问题的最佳方法是什么。

最佳答案

您基本上是在声明和创建该实例时尝试引用类的实例 - 这是不可能的。

我看到您的选项如下:

1。换行警报对话框

这基本上是您使用 ArrayList 的解决方法,但您也可以为此目的创建自己的类。

2。使 AlertDialog 成为成员

alert 声明为包含 doSomething 方法的类的 private 成员,而不是在方法本身中声明它。

3。将 DialogHelper 替换为 Builder

这种方法有几个优点(和一个缺点)。

第一个优点是它可以解决您的问题。第二个是因为它是良好的编码实践:一般来说,具有多个参数的方法被认为是脏的。如果它们是构造函数方法,Clean Code惯例建议用构建器替换它们。

我要建议的实现的缺点是对话框行为是单击选项将始终关闭对话框。

public class MyDialogBuilder {

private AlertDialog alert;

public MyDialogBuilder withActivity(Activity activity){
    final View dView = activity.getLayoutInflater().inflate(R.layout.three_choice_dialog, null);
    alert = ...;
    return this;
}

public MyDialogBuilder withFirstChoice(String choiceText, final ChoiceAction action){
    final TextView firstChoiceTV = (TextView) alert.findViewById(R.id.firstChoiceTV);
    firstChoiceTV.setText(choiceText);
    firstChoiceTV.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            action.perform();
            alert.dismiss();
        }
    });
    return this;
}

// Similar implementations for the other methods here...


public AlertDialog create() {
    return alert;
}

interface ChoiceAction {
    void perform();
}
}

你的调用代码就像这样

MyDialogBuilder builder = new MyDialogBuilder();
    AlertDialog alert = builder.withActivity(activity)
                               .withTitle("Dialog title")
                               .withFirstChoice("choice 1", new MyDialogBuilder.ChoiceAction() {
                                   @Override
                                   public void perform() {
                                       //do something 1
                                   }
                               })
                               .withSecondChoice("choice 2", new MyDialogBuilder.ChoiceAction() {
                                   @Override
                                   public void perform() {
                                       //do something 2
                                   }
                               })
                               .withThirdChoice("choice 3", new MyDialogBuilder.ChoiceAction() {
                                   @Override
                                   public void perform() {
                                       //do something 3
                                   }
                               })
                               .create();

我会推荐第三种方法,因为我认为在大多数情况下您希望在用户选择一个选项时关闭对话框。如果您想在对话框中显示一些进度条,您可以在 MyDialogBu​​ilder 上创建其他方法,该方法将在回调中调用 alert.dismiss()。希望这会有所帮助。

关于java - 如何在内部类初始化时访问自己的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39095555/

相关文章:

android - 如何在 webview 中播放本地 swf 文件

java - 操作栏拉伸(stretch)选项卡

android - 比较 Android 服务内的变量值

java - 方法不打印/返回

java - 不使用未实现的接口(interface)来保存常量的原因是什么?

java - 如何通过JDBC接口(interface)将UTF-8字符串正确写入MySQL

java.lang.NoSuchMethodError : javax. persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode;

java - java中的静态方法main

java - 按自然顺序对字符串数组进行排序并忽略空格

android - 在后台定期进行 Android 应用轮询的最佳方式