Слушатель ноль - PullRequest
0 голосов
/ 13 июня 2018

Я уверен на 100%, что метод onAttach вызывается до onCreate, поэтому как мой слушатель имеет значение null? Как это исправить?По сути, если я смогу получить значения из NameDialog, я назову другое действие (скажем, игру), которое реализует интерфейс NameDialogListener, поэтому я смогу переопределить методы getTexts в игровом действии.

    public class NameDialog extends AppCompatDialogFragment {
    private EditText firstPlayer;
    private EditText secondPlayer;
    private NameDialogListener listener;


    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        LayoutInflater inflater = getActivity().getLayoutInflater();
        final View view = inflater.inflate(R.layout.layout_dialog, null);

        firstPlayer = view.findViewById(R.id.edit_player1);
        secondPlayer = view.findViewById(R.id.edit_player2);

        builder.setView(view)
                .setTitle("Names")
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String player1 = firstPlayer.getText().toString();
                        String player2 = secondPlayer.getText().toString();
                        listener.getTexts(player1, player2);
                        // Intent intent = new Intent(NameDialog.this.getActivity(), Game.class);
                        // startActivity(intent);


                    }
                });

        return builder.create();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
           listener = (NameDialogListener) context;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public interface NameDialogListener {
        void getTexts(String player1, String player2);
    }
}

ОШИБКА - ЛОГ:

/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.anil.tictactoe, PID: 6009
                  **java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.anil.tictactoe.NameDialog$NameDialogListener.getTexts(java.lang.String, java.lang.String)' on a null object reference
                      at com.example.anil.tictactoe.NameDialog$1.onClick(NameDialog.java:43)**
                      at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:175)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6776)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

Ответы [ 4 ]

0 голосов
/ 13 июня 2018

Возможно, проблема в коде, показывающем DialogFragment.Хороший способ отображения DialogFrament - это

new NameDialog (). Show (getSupportFragmentManager (), "my_name_dialog");

Это вызовет onAttach для получения контекста.

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

     @Override public void onAttach(Context context) {
         super.onAttach(context);
         if (context instanceof NameDialogListener) {
             mListener = (NameDialogListener) context;
         } else {
             throw new RuntimeException(context.toString()
                     + " must implement NameDialogListener");
         } 
     }
0 голосов
/ 13 июня 2018

С помощью ссылки listener в анонимном контексте Java создаст окончательную копию члена для использования в анонимном классе.Это означает, что если listener изменяется, изменения не наблюдаются в окончательной копии.

Чтобы исправить это, используйте конкретный класс для OnClickListener и передайте ему слушателя.Это позволит избежать создания окончательной копии.

0 голосов
/ 13 июня 2018

Должно быть сгенерировано исключение, попробуйте зарегистрировать его, или вы можете сделать тост или использовать отладчик, чтобы увидеть, что происходит, onDetach не может быть вызван ранее в onCreate

Контекст, который вы используете, является анонимным, вам следует использовать конкретныйили приведите его туда, где вы реализуете интерфейс

0 голосов
/ 13 июня 2018

1) Исходя из вопроса, кажется, что интерфейс не был должным образом реализован в действии, из которого создается диалоговое окно.

2) Если интерфейс был правильно реализован, вы можете попробовать передатьэкземпляр действия в конструкторе диалогового окна, например:

NameDialog(Activity activity){
     listener = (NameDialogListener) activity;
}

3) (не рекомендуется) Вы также можете попробовать быстрое исправление (устаревший метод) путем переопределения onAttach (действие Activity) вместо onAttach (Context context) .В основном код будет выглядеть как

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
       listener = (NameDialogListener) activity;
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...