簡體   English   中英

內部類初始化后如何訪問自己的變量?

[英]How to access own variable upon initialization within inner class?

我有一個“ DialogHelper”類,其中在各種上下文中使用了一堆靜態方法以使使用Dialogs更容易。 一種這樣的方法是“三選對話框”,其中用戶有三個按鈕可供選擇以前進:

    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.包裝AlertDialog

這基本上是使用ArrayList ,但是您也可以為此創建自己的類。

2.使AlertDialog成為成員

聲明alert是包含doSomething方法的類的private成員,而不是在方法本身中聲明它。

3.用構建器替換DialogHelper

這種方法有幾個優點(一個缺點)。

第一個優點是它將解決您的問題。 第二個原因是因為它是良好的編碼實踐:通常,擁有帶有許多參數的方法被認為是骯臟的。 如果它們是構造函數方法,則“ 干凈代碼”約定建議將其替換為構建器。

我要建議的實現的缺點是,對話框行為是單擊選項將始終關閉對話框。

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();

我建議使用第三種方法,因為我認為在大多數情況下,當用戶選擇一個選項時,您想關閉對話框。 如果要在對話框中顯示進度條,則可以在MyDialogBuilder上創建其他方法,這些方法將在回調中調用alert.dismiss() 希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM